diff --git a/.gitignore b/.gitignore index 6c187836..c8d3e6c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ # Adrian .vscode/ .idea/ -helpmehelpapplication/target -.target/ -.helpmehelpapplication\target/ .helpmehelpapplication\.idea/ diff --git a/docs/ER-DiagramFile.mwb b/docs/ER-DiagramFile.mwb deleted file mode 100644 index c05526f1..00000000 Binary files a/docs/ER-DiagramFile.mwb and /dev/null differ diff --git a/docs/ER-DiagramFile.mwb.bak b/docs/ER-DiagramFile.mwb.bak deleted file mode 100644 index 24c783ba..00000000 Binary files a/docs/ER-DiagramFile.mwb.bak and /dev/null differ diff --git a/docs/Javadoc/apidocs/allclasses-index.html b/docs/Javadoc/apidocs/allclasses-index.html new file mode 100644 index 00000000..69f3e16f --- /dev/null +++ b/docs/Javadoc/apidocs/allclasses-index.html @@ -0,0 +1,218 @@ + + + + +All Classes and Interfaces (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

All Classes and Interfaces

+
+
+
+
+
+
Class
+
Description
+ +
+
Represents data parsed from the IK API JSON response.
+
+ +
+
Fetches JSON information from the IK API and parses the JSON into a list of APICharityData objects.
+
+ +
 
+ +
+
Service class responsible for handling user authentication operations, including login, +registration, and logout functionality.
+
+ +
+
This controller represents the available organization page, where the user can search for a +charity and choose to donate to it.
+
+ +
 
+ +
+
Data access class responsible for getting all the distinct categories from the database.
+
+ +
 
+ +
+
This controller represents the charity page, where the user can read about the charity and choose +to donate to it.
+
+ +
 
+ +
+
Data access class responsible for reading charity-related data from the database.
+
+ +
 
+ +
+
Represents a reusable database connection through enviroment variables.
+
+ +
+
Manages the Database with MySQL tables and test connection.
+
+ +
 
+ +
+
This class is responsible for sending concurrent information about the donation to the Donation +Database.
+
+ +
+
This controller represents the donation page, where the user can enter a donation amount and +confirm their donation to the charity.
+
+ +
 
+ +
+
Data access class responsible for reading donation data from the database.
+
+ +
 
+ +
 
+ +
 
+ +
+
Landing page's controller.
+
+ +
+
Orchestrates a full charity data scrape by combining two data sources: + + + The external charity API (via APICharityScraper), which provides structured data + such as organisation numbers, approval status, and charity URLs.
+
+ +
 
+ +
+
Represents a user's inbox that contains messages.
+
+ +
+
Supported application languages.
+
+ +
+
This class is a utility class that is used to load different scenes in the application.
+
+ +
+
Facilitates downloading of .png images from the individual charity's page on IK, converting them +to bytecode (blob), and then back to a .png.
+
+ +
 
+ +
+
Represents a message.
+
+ +
 
+ +
+
This controller represents the organization card that is displayed on the front page and is +looped upon in FronpageController.
+
+ +
+
A utility for hashing and verifying passwords using PBKDF2.
+
+ +
+
Available users
+
+ +
+
Represents the settings for a user.
+
+ +
+
Class for scraping the description, URL of the logo, string of categories, and key values of the +charities registered in IK.
+
+ +
+
Represents a user in the system.
+
+ +
+
This class is responsible for sending concurrent information about the user to the User database, +and user settings to the settings database.
+
+ +
 
+ +
+
Data access class responsible for reading user-related data from the database.
+
+
+
+
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/allpackages-index.html b/docs/Javadoc/apidocs/allpackages-index.html new file mode 100644 index 00000000..32d366d9 --- /dev/null +++ b/docs/Javadoc/apidocs/allpackages-index.html @@ -0,0 +1,91 @@ + + + + +All Packages (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

All Packages

+
+
Package Summary
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/element-list b/docs/Javadoc/apidocs/element-list new file mode 100644 index 00000000..2113c6a7 --- /dev/null +++ b/docs/Javadoc/apidocs/element-list @@ -0,0 +1,13 @@ +ntnu.systemutvikling.team6 +ntnu.systemutvikling.team6.controller +ntnu.systemutvikling.team6.controller.components +ntnu.systemutvikling.team6.database +ntnu.systemutvikling.team6.database.DAO +ntnu.systemutvikling.team6.database.Readers +ntnu.systemutvikling.team6.models +ntnu.systemutvikling.team6.models.registry +ntnu.systemutvikling.team6.models.user +ntnu.systemutvikling.team6.scraper +ntnu.systemutvikling.team6.scraper.scraperComponents +ntnu.systemutvikling.team6.security +ntnu.systemutvikling.team6.service diff --git a/docs/Javadoc/apidocs/help-doc.html b/docs/Javadoc/apidocs/help-doc.html new file mode 100644 index 00000000..7bd33e3c --- /dev/null +++ b/docs/Javadoc/apidocs/help-doc.html @@ -0,0 +1,224 @@ + + + + +API Help (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+

JavaDoc Help

+
+
+

Navigation

+Starting from the Overview page, you can browse the documentation using the links in each page, and in the navigation bar at the top of each page. The Index and Search box allow you to navigate to specific declarations and summary pages, including: All Packages, All Classes and Interfaces + +
+

Keyboard Navigation

+

Documentation pages provide keyboard shortcuts to facilitate access to common navigation tasks.

+
    +
  • Type +/ + to access the search input field in any page.
  • +
  • Type +. + to access the filter input field in the sidebar of class pages.
  • +
  • Type +Esc + to clear the input and release keyboard focus in any input field.
  • +
  • Type +Tab +/ + +/ + + to select list items after entering a search term in a search or filter input field.
  • +
  • Type + +/ + + to switch between tabs in tabbed summary tables.
  • +
+
+
+
+
+

Kinds of Pages

+The following sections describe the different kinds of pages in this collection. +
+

Overview

+

The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

+
+
+

Package

+

Each package has a page that contains a list of its classes and interfaces, with a summary for each. These pages may contain the following categories:

+
    +
  • Interfaces
  • +
  • Classes
  • +
  • Enum Classes
  • +
  • Exception Classes
  • +
  • Annotation Interfaces
  • +
+
+
+

Class or Interface

+

Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a declaration and description, member summary tables, and detailed member descriptions. Entries in each of these sections are omitted if they are empty or not applicable.

+
    +
  • Class Inheritance Diagram
  • +
  • Direct Subclasses
  • +
  • All Known Subinterfaces
  • +
  • All Known Implementing Classes
  • +
  • Class or Interface Declaration
  • +
  • Class or Interface Description
  • +
+
+
    +
  • Nested Class Summary
  • +
  • Enum Constant Summary
  • +
  • Field Summary
  • +
  • Property Summary
  • +
  • Constructor Summary
  • +
  • Method Summary
  • +
  • Required Element Summary
  • +
  • Optional Element Summary
  • +
+
+
    +
  • Enum Constant Details
  • +
  • Field Details
  • +
  • Property Details
  • +
  • Constructor Details
  • +
  • Method Details
  • +
  • Element Details
  • +
+

Note: Annotation interfaces have required and optional elements, but not methods. Only enum classes have enum constants. The components of a record class are displayed as part of the declaration of the record class. Properties are a feature of JavaFX.

+

The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

+
+
+

Other Files

+

Packages and modules may contain pages with additional information related to the declarations nearby.

+
+
+

Use

+

Each documented package, class or interface has its own Use page, which lists packages, classes, interfaces, methods, constructors and fields that use any part of that package, class or interface. Given a class or interface A, its Use page includes subclasses or subinterfaces of A, fields declared as A, methods that return A, methods and constructors with parameters of type A, and subclasses or subinterfaces with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the USE link in the navigation bar.

+
+
+

Tree (Class Hierarchy)

+

There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. Classes are organized by inheritance structure starting with java.lang.Object. Interfaces do not inherit from java.lang.Object.

+
    +
  • When viewing the Overview page, clicking on TREE displays the hierarchy for all packages.
  • +
  • When viewing a particular package, class or interface page, clicking on TREE displays the hierarchy for only that package.
  • +
+
+
+

Serialized Form

+

Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to those who implement rather than use the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See Also" section of the class description.

+
+
+

All Packages

+

The All Packages page contains an alphabetic index of all packages contained in the documentation.

+
+
+

All Classes and Interfaces

+

The All Classes and Interfaces page contains an alphabetic index of all classes and interfaces contained in the documentation, including annotation interfaces, enum classes, and record classes.

+
+
+

Index

+

The Index contains an alphabetic index of all classes, interfaces, constructors, methods, and fields in the documentation, as well as summary pages such as All Packages, All Classes and Interfaces.

+
+
+
+
+

Release Details

+

The details for each module, package, class or interface normally include the release in which the declaration was introduced.

+

When a member is added after the initial introduction of the enclosing class or interface, the details of the member include the release in which it was introduced.

+
+
+This help file applies to API documentation generated by the standard doclet. + +
+
+ + diff --git a/docs/Javadoc/apidocs/index-all.html b/docs/Javadoc/apidocs/index-all.html new file mode 100644 index 00000000..256bbe72 --- /dev/null +++ b/docs/Javadoc/apidocs/index-all.html @@ -0,0 +1,977 @@ + + + + +Index (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Index

+
+A B C D E F G H I L M N O P R S T U V 
All Classes and Interfaces|All Packages +

A

+
+
addAPIDataToTable(List) - Method in class ntnu.systemutvikling.team6.service.APIToDatabaseService
+
+
This method is used to verify the integrity of the data in the charities table and to +update it based on the data retrieved from the IK API and the charity's URL.
+
+
addCharity(Charity) - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
addDonation(Charity, User, double) - Method in class ntnu.systemutvikling.team6.database.DAO.DonationDAO
+
+
Gets the total ammount of donations for a given charity, and sends it to the database throught +MySQL.
+
+
addDonation(Donation) - Method in class ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
 
+
addMessage(Message) - Method in class ntnu.systemutvikling.team6.models.user.Inbox
+
+
Add´s message to the messages list.
+
+
addUser(User) - Method in class ntnu.systemutvikling.team6.models.registry.UserRegistry
+
 
+
APICharityData - Class in ntnu.systemutvikling.team6.scraper.scraperComponents
+
+
Represents data parsed from the IK API JSON response.
+
+
APICharityData(String, String, String, String, boolean) - Constructor for class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Constructs a new APICharityData object.
+
+
APICharityScraper - Class in ntnu.systemutvikling.team6.scraper.scraperComponents
+
+
Fetches JSON information from the IK API and parses the JSON into a list of APICharityData objects.
+
+
APICharityScraper(HttpClient) - Constructor for class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper
+
+
Constructs a new APICharityScraper object.
+
+
APIToDatabaseService - Class in ntnu.systemutvikling.team6.service
+
 
+
APIToDatabaseService(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.service.APIToDatabaseService
+
+
Contractor for APIToDatabaseService.
+
+
AuthenticationService - Class in ntnu.systemutvikling.team6.service
+
+
Service class responsible for handling user authentication operations, including login, +registration, and logout functionality.
+
+
AuthenticationService(UserSelect, UserDAO) - Constructor for class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Constructs an AuthenticationService with the specified data access objects.
+
+
authToken - Variable in class ntnu.systemutvikling.team6.controller.components.BaseController
+
 
+
authTokenisSet() - Method in class ntnu.systemutvikling.team6.controller.components.BaseController
+
 
+
authTokenisSet() - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
 
+
AvailableOrganizationController - Class in ntnu.systemutvikling.team6.controller
+
+
This controller represents the available organization page, where the user can search for a +charity and choose to donate to it.
+
+
AvailableOrganizationController() - Constructor for class ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
 
+
+

B

+
+
BaseController - Class in ntnu.systemutvikling.team6.controller.components
+
 
+
BaseController() - Constructor for class ntnu.systemutvikling.team6.controller.components.BaseController
+
 
+
+

C

+
+
CategorySelect - Class in ntnu.systemutvikling.team6.database.Readers
+
+
Data access class responsible for getting all the distinct categories from the database.
+
+
CategorySelect(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.Readers.CategorySelect
+
+
Constructs a new CharitySelect with the given database connection.
+
+
changeLanguage(Language) - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
+
Change language to the chosen language.
+
+
Charity - Class in ntnu.systemutvikling.team6.models
+
 
+
Charity(String, String, Boolean, String) - Constructor for class ntnu.systemutvikling.team6.models.Charity
+
+
Minimal contructor JUST FOR DONATIONSSELECT.
+
+
Charity(String, String, String, boolean, String) - Constructor for class ntnu.systemutvikling.team6.models.Charity
+
+
Contructor for creating a new charity.
+
+
Charity(String, String, String, String, String, boolean, String, String, String, byte[]) - Constructor for class ntnu.systemutvikling.team6.models.Charity
+
+
Contructor for creating a new charity.
+
+
CHARITY_USER - Enum constant in enum class ntnu.systemutvikling.team6.models.user.Role
+
 
+
CharityPageController - Class in ntnu.systemutvikling.team6.controller
+
+
This controller represents the charity page, where the user can read about the charity and choose +to donate to it.
+
+
CharityPageController() - Constructor for class ntnu.systemutvikling.team6.controller.CharityPageController
+
 
+
CharityRegistry - Class in ntnu.systemutvikling.team6.models.registry
+
 
+
CharityRegistry() - Constructor for class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
CharitySelect - Class in ntnu.systemutvikling.team6.database.Readers
+
+
Data access class responsible for reading charity-related data from the database.
+
+
CharitySelect(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.Readers.CharitySelect
+
+
Constructs a new CharitySelect with the given database connection.
+
+
CharityService - Class in ntnu.systemutvikling.team6.service
+
 
+
CharityService() - Constructor for class ntnu.systemutvikling.team6.service.CharityService
+
 
+
checkConnection() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper
+
+
Checks if the http request returns an 'OK' response.
+
+
checkPassword(String) - Method in class ntnu.systemutvikling.team6.models.user.User
+
+
Checks if the provided password matches the stored password.
+
+
closeDriver() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Quits the driver instance, making it unusable.
+
+
convertBlobToPNG(byte[], String) - Static method in class ntnu.systemutvikling.team6.scraper.LogoDownloader
+
+
Converts a blob of image data back to a .png image file.
+
+
createTables() - Method in class ntnu.systemutvikling.team6.database.DatabaseSetup
+
+
Creates the Charities and Donations tables if they do not already exist.
+
+
createWait() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Creates a WebDriverWait object for halting scraping until the correct pre-conditions +are met.
+
+
+

D

+
+
DatabaseConnection - Class in ntnu.systemutvikling.team6.database
+
+
Represents a reusable database connection through enviroment variables.
+
+
DatabaseConnection() - Constructor for class ntnu.systemutvikling.team6.database.DatabaseConnection
+
+
Constructs a new DatabaseConnection using database credentials retrieved from system +environment variables.
+
+
DatabaseConnection(String, String, String) - Constructor for class ntnu.systemutvikling.team6.database.DatabaseConnection
+
+
Constructs a new DatabaseConnection using database credentials
+
+
DatabaseSetup - Class in ntnu.systemutvikling.team6.database
+
+
Manages the Database with MySQL tables and test connection.
+
+
DatabaseSetup(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.DatabaseSetup
+
+
Contractor for DatabaseManager.
+
+
Donate(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
This method is used to process the donation when the user clicks the donate button.
+
+
Donation - Class in ntnu.systemutvikling.team6.models
+
 
+
Donation(double, LocalDate, Charity, User) - Constructor for class ntnu.systemutvikling.team6.models.Donation
+
+
Constructor for creating a new donation.
+
+
Donation(String, double, LocalDate, Charity, User, boolean) - Constructor for class ntnu.systemutvikling.team6.models.Donation
+
+
Constructor for creating a donation reed from the database.
+
+
DonationDAO - Class in ntnu.systemutvikling.team6.database.DAO
+
+
This class is responsible for sending concurrent information about the donation to the Donation +Database.
+
+
DonationDAO(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.DAO.DonationDAO
+
 
+
DonationPageController - Class in ntnu.systemutvikling.team6.controller
+
+
This controller represents the donation page, where the user can enter a donation amount and +confirm their donation to the charity.
+
+
DonationPageController() - Constructor for class ntnu.systemutvikling.team6.controller.DonationPageController
+
 
+
DonationRegistry - Class in ntnu.systemutvikling.team6.models.registry
+
 
+
DonationRegistry() - Constructor for class ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
 
+
DonationSelect - Class in ntnu.systemutvikling.team6.database.Readers
+
+
Data access class responsible for reading donation data from the database.
+
+
DonationSelect(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.Readers.DonationSelect
+
+
Constructs a new DonationSelect with the given database connection.
+
+
DonationService - Class in ntnu.systemutvikling.team6.service
+
 
+
DonationService() - Constructor for class ntnu.systemutvikling.team6.service.DonationService
+
 
+
downloadImageAsBlob(String) - Static method in class ntnu.systemutvikling.team6.scraper.LogoDownloader
+
+
Downloads a image from the given URL and converts it to a blob.
+
+
+

E

+
+
ENGLISH - Enum constant in enum class ntnu.systemutvikling.team6.models.user.Language
+
 
+
+

F

+
+
Feedback - Class in ntnu.systemutvikling.team6.models
+
 
+
Feedback(String, User, String, LocalDate) - Constructor for class ntnu.systemutvikling.team6.models.Feedback
+
+
Constructor for creating a new feedback, based on making a feedback previously made.
+
+
Feedback(User, String) - Constructor for class ntnu.systemutvikling.team6.models.Feedback
+
+
Constructor for creating a new feedback now.
+
+
FeedbackService - Class in ntnu.systemutvikling.team6.service
+
 
+
FeedbackService() - Constructor for class ntnu.systemutvikling.team6.service.FeedbackService
+
 
+
findCharityByOrgnumber(String) - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
findCharityByUUID(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
findDonationById(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
 
+
findElement(By) - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Calls the findElement method from the WebDriver object and returns a list of +the returned WebElement objects.
+
+
findElements(By) - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Calls the findElements method from the WebDriver object and returns a list of +the returned WebElement objects.
+
+
findMessageById(UUID) - Method in class ntnu.systemutvikling.team6.models.user.Inbox
+
+
Finds a specific message by id.
+
+
findUserById(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.UserRegistry
+
 
+
FrontpageController - Class in ntnu.systemutvikling.team6.controller
+
+
Landing page's controller.
+
+
FrontpageController() - Constructor for class ntnu.systemutvikling.team6.controller.FrontpageController
+
 
+
FullCharityScrape - Class in ntnu.systemutvikling.team6.scraper
+
+
Orchestrates a full charity data scrape by combining two data sources: + + + The external charity API (via APICharityScraper), which provides structured data + such as organisation numbers, approval status, and charity URLs.
+
+
FullCharityScrape() - Constructor for class ntnu.systemutvikling.team6.scraper.FullCharityScrape
+
+
Constructs a FullCharityScrape instance and initialises the APICharityScraper +with a new HttpClient.
+
+
+

G

+
+
getAllCharities() - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
getAllDonations() - Method in class ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
 
+
getAllUsers() - Method in class ntnu.systemutvikling.team6.models.registry.UserRegistry
+
 
+
getAmount() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getAPIAndURLCharityData() - Method in class ntnu.systemutvikling.team6.scraper.FullCharityScrape
+
+
Performs a full two-phase scrape and returns a CharityRegistry populated with all +available charity data.
+
+
getAPIScraper() - Method in class ntnu.systemutvikling.team6.scraper.FullCharityScrape
+
 
+
getCategories() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Returns a String of the categories for the charity with ',' as a delimiter.
+
+
getCategoriesFromDB() - Method in class ntnu.systemutvikling.team6.database.Readers.CategorySelect
+
+
Retrieves all the categories listed in the Category table of the database.
+
+
getCategory() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getCharitiesFromDB() - Method in class ntnu.systemutvikling.team6.database.Readers.CharitySelect
+
+
Retrieves all charities from the database, including their associated feedback and the users +who submitted each piece of feedback.
+
+
getCharity() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getCharityId() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getComment() - Method in class ntnu.systemutvikling.team6.models.Feedback
+
 
+
getContent() - Method in class ntnu.systemutvikling.team6.models.user.Message
+
 
+
getCurrentUser() - Method in class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Returns the currently authenticated user.
+
+
getDate() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getDate() - Method in class ntnu.systemutvikling.team6.models.Feedback
+
 
+
getDescription() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getDescription() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Returns the description of the charity.
+
+
getDisplayName() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getDonationFromDB() - Method in class ntnu.systemutvikling.team6.database.Readers.DonationSelect
+
+
Retrieves all donations from the database, each populated with its associated Charity.
+
+
getDonationID() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getDonor() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
getEmail() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getFeedbackforCharityUUID(String) - Method in class ntnu.systemutvikling.team6.database.Readers.CharitySelect
+
+
A helper function that retrieves all feedback entries associated with a specific charity, +identified by its UUID.
+
+
getFeedbackId() - Method in class ntnu.systemutvikling.team6.models.Feedback
+
+
Getters for the feedback's attributes.
+
+
getFeedbacks() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getFrom() - Method in class ntnu.systemutvikling.team6.models.user.Message
+
 
+
getHashPassword(String) - Method in class ntnu.systemutvikling.team6.security.PasswordHasher
+
+
Hashes a password using PBKDF2 and a random salt.
+
+
getId() - Method in class ntnu.systemutvikling.team6.models.user.Message
+
 
+
getId() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getInbox() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getInboxForUser(String) - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Retrieves the Inbox for a specific user by their UUID, populated with all of their +Message objects.
+
+
getIs_pre_approved() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Returns whether the organization was pre-approved.
+
+
getJSONData() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper
+
+
Fetches the JSON data from the IK API and stores it in a String.
+
+
getKeyValues() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getKeyValues() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Returns a String of the key value percentages for the charity with ':' as a delimiter, verified +by IK.
+
+
getLanguage() - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
 
+
getLogoBlob() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getLogoURL() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getLogoURL() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Returns the URL of the logo for the charity.
+
+
getMessages() - Method in class ntnu.systemutvikling.team6.models.user.Inbox
+
+
Returns an unmodifiable view of the messages in this inbox.
+
+
getMySqlConnection() - Method in class ntnu.systemutvikling.team6.database.DatabaseConnection
+
+
Creates and returns a new MySQL database connection.
+
+
getName() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getName() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Returns the name of the organization.
+
+
getOrg_number() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getOrg_number() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Returns the organization number.
+
+
getPasswordHash() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getPreApproved() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getRole() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getSettings() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getSettingsForUser(String) - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Retrieves the Settings for a specific user by their UUID.
+
+
getStatus() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getStatus() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Returns whether the organization is approved or not
+
+
getTimeAndDate() - Method in class ntnu.systemutvikling.team6.models.user.Message
+
 
+
getTitle() - Method in class ntnu.systemutvikling.team6.models.user.Message
+
 
+
getUrl() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
Returns the URL of the organizations information page on IK
+
+
getURL() - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
getUser() - Method in class ntnu.systemutvikling.team6.models.Feedback
+
 
+
getUserFromDBUsernameAndPassword(String, String) - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Retrieves a single User from the database matching the given username and password.
+
+
getUserFromDBUuid(String) - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Retrieves a single User from the database by their UUID.
+
+
getUsername() - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
getUsersFromDB() - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Retrieves all users from the database, each fully populated with their Settings and +Inbox.
+
+
getUUID() - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Getters for the charity's attributes.
+
+
+

H

+
+
handleCategoryFilterChange(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
+
This method is used to filter the charities based on the selected filters.
+
+
handleFrontSearch(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
+
This method is used to search for charities based on the input in the search field.
+
+
handleHomepageClick(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
+
Opens OS default webbrowser and loads the url of the charity on click.
+
+
handleSearch(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
+
This method is used to search for charities based on the input in the search field.
+
+
handleSearch(ActionEvent) - Method in interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController
+
 
+
handleSearch(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
This method is used to handle the search action when the user clicks the search button.
+
+
HmHApplication - Class in ntnu.systemutvikling.team6
+
 
+
HmHApplication() - Constructor for class ntnu.systemutvikling.team6.HmHApplication
+
 
+
+

I

+
+
Inbox - Class in ntnu.systemutvikling.team6.models.user
+
+
Represents a user's inbox that contains messages.
+
+
Inbox() - Constructor for class ntnu.systemutvikling.team6.models.user.Inbox
+
+
Creates an empty inbox with no messages.
+
+
init() - Method in class ntnu.systemutvikling.team6.HmHApplication
+
 
+
initialize() - Method in class ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
+
This method is used to initialize the available organization page.
+
+
initialize() - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
 
+
initialize() - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
+
Initialize method for the front page.
+
+
isAnonymous() - Method in class ntnu.systemutvikling.team6.models.Donation
+
 
+
isAnonymous() - Method in class ntnu.systemutvikling.team6.models.Feedback
+
 
+
isAnonymous() - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
 
+
isLightMode() - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
 
+
isLoggedin() - Method in class ntnu.systemutvikling.team6.controller.components.BaseController
+
 
+
isLoggedin() - Method in class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Checks whether a user is currently logged in.
+
+
isUsernameTaken(String) - Method in class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
 
+
isValidPassword(String, String) - Method in class ntnu.systemutvikling.team6.security.PasswordHasher
+
+
Checks if the password matches a perviously stored hash.
+
+
+

L

+
+
Language - Enum Class in ntnu.systemutvikling.team6.models.user
+
+
Supported application languages.
+
+
LoaderScene - Class in ntnu.systemutvikling.team6.controller.components
+
+
This class is a utility class that is used to load different scenes in the application.
+
+
LoaderScene() - Constructor for class ntnu.systemutvikling.team6.controller.components.LoaderScene
+
 
+
LoadScene(String, ActionEvent, Charity, String) - Static method in class ntnu.systemutvikling.team6.controller.components.LoaderScene
+
+
When going to a new scene, this method is called to load the new scene.
+
+
login(String, String) - Method in class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Attempts to authenticate a user with the given credentials.
+
+
LogoDownloader - Class in ntnu.systemutvikling.team6.scraper
+
+
Facilitates downloading of .png images from the individual charity's page on IK, converting them +to bytecode (blob), and then back to a .png.
+
+
LogoDownloader() - Constructor for class ntnu.systemutvikling.team6.scraper.LogoDownloader
+
 
+
logout() - Method in class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Logs out the currently authenticated user by clearing the current user state.
+
+
+

M

+
+
main(String[]) - Static method in class ntnu.systemutvikling.team6.HmHApplication
+
 
+
main(String[]) - Static method in class ntnu.systemutvikling.team6.Main
+
 
+
Main - Class in ntnu.systemutvikling.team6
+
 
+
Main() - Constructor for class ntnu.systemutvikling.team6.Main
+
 
+
Message - Class in ntnu.systemutvikling.team6.models.user
+
+
Represents a message.
+
+
Message(String, UUID, String) - Constructor for class ntnu.systemutvikling.team6.models.user.Message
+
+
Creates a message with a unique identifier.
+
+
Message(String, UUID, String, LocalDate) - Constructor for class ntnu.systemutvikling.team6.models.user.Message
+
+
Creates a message with a unique identifier.
+
+
+

N

+
+
NavbarFooterController - Interface in ntnu.systemutvikling.team6.controller.components
+
 
+
NORMAL_USER - Enum constant in enum class ntnu.systemutvikling.team6.models.user.Role
+
 
+
NORWEGIAN - Enum constant in enum class ntnu.systemutvikling.team6.models.user.Language
+
 
+
ntnu.systemutvikling.team6 - package ntnu.systemutvikling.team6
+
 
+
ntnu.systemutvikling.team6.controller - package ntnu.systemutvikling.team6.controller
+
 
+
ntnu.systemutvikling.team6.controller.components - package ntnu.systemutvikling.team6.controller.components
+
 
+
ntnu.systemutvikling.team6.database - package ntnu.systemutvikling.team6.database
+
 
+
ntnu.systemutvikling.team6.database.DAO - package ntnu.systemutvikling.team6.database.DAO
+
 
+
ntnu.systemutvikling.team6.database.Readers - package ntnu.systemutvikling.team6.database.Readers
+
 
+
ntnu.systemutvikling.team6.models - package ntnu.systemutvikling.team6.models
+
 
+
ntnu.systemutvikling.team6.models.registry - package ntnu.systemutvikling.team6.models.registry
+
 
+
ntnu.systemutvikling.team6.models.user - package ntnu.systemutvikling.team6.models.user
+
 
+
ntnu.systemutvikling.team6.scraper - package ntnu.systemutvikling.team6.scraper
+
 
+
ntnu.systemutvikling.team6.scraper.scraperComponents - package ntnu.systemutvikling.team6.scraper.scraperComponents
+
 
+
ntnu.systemutvikling.team6.security - package ntnu.systemutvikling.team6.security
+
 
+
ntnu.systemutvikling.team6.service - package ntnu.systemutvikling.team6.service
+
 
+
+

O

+
+
OrganizationCardController - Class in ntnu.systemutvikling.team6.controller.components
+
+
This controller represents the organization card that is displayed on the front page and is +looped upon in FronpageController.
+
+
OrganizationCardController() - Constructor for class ntnu.systemutvikling.team6.controller.components.OrganizationCardController
+
 
+
+

P

+
+
parseJSON(String) - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper
+
+
Parses the JSON data using gson and translates the APICharityData into our predefined +charity classes and puts it in a CharityRegistry object.
+
+
PasswordHasher - Class in ntnu.systemutvikling.team6.security
+
+
A utility for hashing and verifying passwords using PBKDF2.
+
+
PasswordHasher() - Constructor for class ntnu.systemutvikling.team6.security.PasswordHasher
+
 
+
processDonation(Charity, User, double) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
Invoke DAO object to add the donation to the database.
+
+
+

R

+
+
register(String, String, String, String) - Method in class ntnu.systemutvikling.team6.service.AuthenticationService
+
+
Registers a new user account with the provided details.
+
+
registerUser(User) - Method in class ntnu.systemutvikling.team6.database.DAO.UserDAO
+
+
Gets the user and settings information and sends it to the database through MySQL.
+
+
removeCharity(String) - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
removeCharityUUID(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
 
+
removeDonation(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
 
+
removeMessage(UUID) - Method in class ntnu.systemutvikling.team6.models.user.Inbox
+
+
Removes a message from the inbox list.
+
+
removeUserByUUID(UUID) - Method in class ntnu.systemutvikling.team6.models.registry.UserRegistry
+
 
+
Role - Enum Class in ntnu.systemutvikling.team6.models.user
+
+
Available users
+
+
+

S

+
+
scrapeCharityPage() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Runs all the scraper methods at once, updating the object parameters.
+
+
setAuthToken(AuthenticationService) - Method in class ntnu.systemutvikling.team6.controller.components.BaseController
+
 
+
setCategories(List) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
+
Takes a list of categories for the charities and populates a scroll pane with labels containing +the charities.
+
+
setCategory(List) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for categories.
+
+
setCharity(Charity) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
+
This method is used to set the charity that is being displayed on the page.
+
+
setCharity(Charity) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
Initialize method for the donation page.
+
+
setDescription(String) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for description.
+
+
setEmail(String) - Method in class ntnu.systemutvikling.team6.models.user.User
+
+
Updates the users email.
+
+
setFeedbacks(ArrayList) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for setting feedbacks
+
+
setInbox(Inbox) - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
setInitialSearch(String) - Method in class ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
+
This method is used to set the initial search query in the search field.
+
+
setKeyValues(String) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for the charity's key values.
+
+
setLogoBlob(byte[]) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for the charity's logo Blob.
+
+
setLogoURL(String) - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for the URL of the charity's logo.
+
+
setOrganization(Charity) - Method in class ntnu.systemutvikling.team6.controller.components.OrganizationCardController
+
 
+
setPassword(String) - Method in class ntnu.systemutvikling.team6.models.user.User
+
+
Updates the users password.
+
+
setSettings(Settings) - Method in class ntnu.systemutvikling.team6.models.user.User
+
 
+
Settings - Class in ntnu.systemutvikling.team6.models.user
+
+
Represents the settings for a user.
+
+
Settings() - Constructor for class ntnu.systemutvikling.team6.models.user.Settings
+
+
Sets standard settings.
+
+
Settings(boolean, Language, boolean) - Constructor for class ntnu.systemutvikling.team6.models.user.Settings
+
+
Creates settings for a user.
+
+
setUnverified() - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for verification status.
+
+
setUsername(String) - Method in class ntnu.systemutvikling.team6.models.user.User
+
+
Updates the users name.
+
+
setUUIDFromString(String) - Method in class ntnu.systemutvikling.team6.models.Charity
+
 
+
setVerified() - Method in class ntnu.systemutvikling.team6.models.Charity
+
+
Setter for verification status.
+
+
start(Stage) - Method in class ntnu.systemutvikling.team6.HmHApplication
+
 
+
switchToAboutPage(ActionEvent) - Method in interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController
+
 
+
switchToCharityPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
+
This method is used to switch to the charity page for the selected charity.
+
+
switchToCharityPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.components.OrganizationCardController
+
 
+
switchToCharityPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
This method is used to switch back to the Donation page when the user clicks the back button.
+
+
switchToCharityPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
+
This method is used to switch to the charity page for the selected charity
+
+
switchToDonationPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
+
This method is used to switch to the donation page.
+
+
switchToDonationPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
+
This method is used to switch to the donation page.
+
+
switchToDonationPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.components.OrganizationCardController
+
 
+
switchToDonationPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.FrontpageController
+
+
This method is used to switch to the donation page for the selected charity.
+
+
switchToFrontPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.CharityPageController
+
 
+
switchToFrontPage(ActionEvent) - Method in interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController
+
 
+
switchToFrontPage(ActionEvent) - Method in class ntnu.systemutvikling.team6.controller.DonationPageController
+
+
This method is used to switch back to the front page when the user clicks the back button.
+
+
switchToLoginPage(ActionEvent) - Method in interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController
+
 
+
switchToProfilePage(ActionEvent) - Method in interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController
+
 
+
+

T

+
+
testConnection() - Method in class ntnu.systemutvikling.team6.database.DatabaseSetup
+
+
Connection test for the Database.
+
+
toggleAnonymousMode() - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
+
Toggles anonymous mode on and off
+
+
toggleLightMode() - Method in class ntnu.systemutvikling.team6.models.user.Settings
+
+
Toggles between light and dark mode
+
+
+

U

+
+
updateDescription() - Method in class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Scrapes the URL for the paragraphs containing the description of the charity.
+
+
URLCharityScraper - Class in ntnu.systemutvikling.team6.scraper.scraperComponents
+
+
Class for scraping the description, URL of the logo, string of categories, and key values of the +charities registered in IK.
+
+
URLCharityScraper(String) - Constructor for class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Constructor used for production code.
+
+
URLCharityScraper(String, WebDriver) - Constructor for class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
Constructor used for testing.
+
+
User - Class in ntnu.systemutvikling.team6.models.user
+
+
Represents a user in the system.
+
+
User(String, String, String, String, String, String) - Constructor for class ntnu.systemutvikling.team6.models.user.User
+
+
Creates a new user taylored for getting info from DATABASE.
+
+
User(String, String, String, String, Role, Settings, Inbox) - Constructor for class ntnu.systemutvikling.team6.models.user.User
+
+
Creates a new user.
+
+
UserDAO - Class in ntnu.systemutvikling.team6.database.DAO
+
+
This class is responsible for sending concurrent information about the user to the User database, +and user settings to the settings database.
+
+
UserDAO(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.DAO.UserDAO
+
 
+
UserRegistry - Class in ntnu.systemutvikling.team6.models.registry
+
 
+
UserRegistry() - Constructor for class ntnu.systemutvikling.team6.models.registry.UserRegistry
+
 
+
UserSelect - Class in ntnu.systemutvikling.team6.database.Readers
+
+
Data access class responsible for reading user-related data from the database.
+
+
UserSelect(DatabaseConnection) - Constructor for class ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
Constructs a new UserSelect with the given database connection.
+
+
+

V

+
+
valueOf(String) - Static method in enum class ntnu.systemutvikling.team6.models.user.Language
+
+
Returns the enum constant of this class with the specified name.
+
+
valueOf(String) - Static method in enum class ntnu.systemutvikling.team6.models.user.Role
+
+
Returns the enum constant of this class with the specified name.
+
+
values() - Static method in enum class ntnu.systemutvikling.team6.models.user.Language
+
+
Returns an array containing the constants of this enum class, in +the order they are declared.
+
+
values() - Static method in enum class ntnu.systemutvikling.team6.models.user.Role
+
+
Returns an array containing the constants of this enum class, in +the order they are declared.
+
+
+A B C D E F G H I L M N O P R S T U V 
All Classes and Interfaces|All Packages + +
+
+ + diff --git a/docs/Javadoc/apidocs/index.html b/docs/Javadoc/apidocs/index.html new file mode 100644 index 00000000..3ad49dd3 --- /dev/null +++ b/docs/Javadoc/apidocs/index.html @@ -0,0 +1,93 @@ + + + + +Overview (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

helpmehelpapplication 1.0-SNAPSHOT API

+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/javadoc.bat b/docs/Javadoc/apidocs/javadoc.bat new file mode 100644 index 00000000..2dd43051 --- /dev/null +++ b/docs/Javadoc/apidocs/javadoc.bat @@ -0,0 +1 @@ +cmd.exe /X /D /C ""C:\Program Files\Java\jdk-25\bin\javadoc.exe" -J-Duser.language= -J-Duser.country= @options @packages" \ No newline at end of file diff --git a/docs/Javadoc/apidocs/legal/COPYRIGHT b/docs/Javadoc/apidocs/legal/COPYRIGHT new file mode 100644 index 00000000..7a42888b --- /dev/null +++ b/docs/Javadoc/apidocs/legal/COPYRIGHT @@ -0,0 +1,69 @@ +Copyright © 1993, 2025, Oracle and/or its affiliates. +All rights reserved. + +This software and related documentation are provided under a +license agreement containing restrictions on use and +disclosure and are protected by intellectual property laws. +Except as expressly permitted in your license agreement or +allowed by law, you may not use, copy, reproduce, translate, +broadcast, modify, license, transmit, distribute, exhibit, +perform, publish, or display any part, in any form, or by +any means. Reverse engineering, disassembly, or +decompilation of this software, unless required by law for +interoperability, is prohibited. + +The information contained herein is subject to change +without notice and is not warranted to be error-free. If you +find any errors, please report them to us in writing. + +If this is software or related documentation that is +delivered to the U.S. Government or anyone licensing it on +behalf of the U.S. Government, the following notice is +applicable: + +U.S. GOVERNMENT END USERS: Oracle programs, including any +operating system, integrated software, any programs +installed on the hardware, and/or documentation, delivered +to U.S. Government end users are "commercial computer +software" pursuant to the applicable Federal Acquisition +Regulation and agency-specific supplemental regulations. As +such, use, duplication, disclosure, modification, and +adaptation of the programs, including any operating system, +integrated software, any programs installed on the hardware, +and/or documentation, shall be subject to license terms and +license restrictions applicable to the programs. No other +rights are granted to the U.S. Government. + +This software or hardware is developed for general use in a +variety of information management applications. It is not +developed or intended for use in any inherently dangerous +applications, including applications that may create a risk +of personal injury. If you use this software or hardware in +dangerous applications, then you shall be responsible to +take all appropriate fail-safe, backup, redundancy, and +other measures to ensure its safe use. Oracle Corporation +and its affiliates disclaim any liability for any damages +caused by use of this software or hardware in dangerous +applications. + +Oracle and Java are registered trademarks of Oracle and/or +its affiliates. Other names may be trademarks of their +respective owners. + +Intel and Intel Xeon are trademarks or registered trademarks +of Intel Corporation. All SPARC trademarks are used under +license and are trademarks or registered trademarks of SPARC +International, Inc. AMD, Opteron, the AMD logo, and the AMD +Opteron logo are trademarks or registered trademarks of +Advanced Micro Devices. UNIX is a registered trademark of +The Open Group. + +This software or hardware and documentation may provide +access to or information on content, products, and services +from third parties. Oracle Corporation and its affiliates +are not responsible for and expressly disclaim all +warranties of any kind with respect to third-party content, +products, and services. Oracle Corporation and its +affiliates will not be responsible for any loss, costs, or +damages incurred due to your access to or use of third-party +content, products, or services. diff --git a/docs/Javadoc/apidocs/legal/LICENSE b/docs/Javadoc/apidocs/legal/LICENSE new file mode 100644 index 00000000..ee860d38 --- /dev/null +++ b/docs/Javadoc/apidocs/legal/LICENSE @@ -0,0 +1,118 @@ +Your use of this Program is governed by the No-Fee Terms and Conditions set +forth below, unless you have received this Program (alone or as part of another +Oracle product) under an Oracle license agreement (including but not limited to +the Oracle Master Agreement), in which case your use of this Program is governed +solely by such license agreement with Oracle. + +Oracle No-Fee Terms and Conditions (NFTC) + +Definitions + +"Oracle" refers to Oracle America, Inc. "You" and "Your" refers to (a) a company +or organization (each an "Entity") accessing the Programs, if use of the +Programs will be on behalf of such Entity; or (b) an individual accessing the +Programs, if use of the Programs will not be on behalf of an Entity. +"Program(s)" refers to Oracle software provided by Oracle pursuant to the +following terms and any updates, error corrections, and/or Program Documentation +provided by Oracle. "Program Documentation" refers to Program user manuals and +Program installation manuals, if any. If available, Program Documentation may be +delivered with the Programs and/or may be accessed from +www.oracle.com/documentation. "Separate Terms" refers to separate license terms +that are specified in the Program Documentation, readmes or notice files and +that apply to Separately Licensed Technology. "Separately Licensed Technology" +refers to Oracle or third party technology that is licensed under Separate Terms +and not under the terms of this license. + +Separately Licensed Technology + +Oracle may provide certain notices to You in Program Documentation, readmes or +notice files in connection with Oracle or third party technology provided as or +with the Programs. If specified in the Program Documentation, readmes or notice +files, such technology will be licensed to You under Separate Terms. Your rights +to use Separately Licensed Technology under Separate Terms are not restricted in +any way by the terms herein. For clarity, notwithstanding the existence of a +notice, third party technology that is not Separately Licensed Technology shall +be deemed part of the Programs licensed to You under the terms of this license. + +Source Code for Open Source Software + +For software that You receive from Oracle in binary form that is licensed under +an open source license that gives You the right to receive the source code for +that binary, You can obtain a copy of the applicable source code from +https://oss.oracle.com/sources/ or http://www.oracle.com/goto/opensourcecode. If +the source code for such software was not provided to You with the binary, You +can also receive a copy of the source code on physical media by submitting a +written request pursuant to the instructions in the "Written Offer for Source +Code" section of the latter website. + +------------------------------------------------------------------------------- + +The following license terms apply to those Programs that are not provided to You +under Separate Terms. + +License Rights and Restrictions + +Oracle grants to You, as a recipient of this Program, subject to the conditions +stated herein, a nonexclusive, nontransferable, limited license to: + +(a) internally use the unmodified Programs for the purposes of developing, +testing, prototyping and demonstrating your applications, and running the +Program for Your own personal use or internal business operations; and + +(b) redistribute the unmodified Program and Program Documentation, under the +terms of this License, provided that You do not charge Your licensees any fees +associated with such distribution or use of the Program, including, without +limitation, fees for products that include or are bundled with a copy of the +Program or for services that involve the use of the distributed Program. + +You may make copies of the Programs to the extent reasonably necessary for +exercising the license rights granted herein and for backup purposes. You are +granted the right to use the Programs to provide third party training in the use +of the Programs and associated Separately Licensed Technology only if there is +express authorization of such use by Oracle on the Program's download page or in +the Program Documentation. + +Your license is contingent on compliance with the following conditions: + +- You do not remove markings or notices of either Oracle's or a licensor's + proprietary rights from the Programs or Program Documentation; + +- You comply with all U.S. and applicable export control and economic sanctions + laws and regulations that govern Your use of the Programs (including technical + data); + +- You do not cause or permit reverse engineering, disassembly or decompilation + of the Programs (except as allowed by law) by You nor allow an associated + party to do so. + +For clarity, any source code that may be included in the distribution with the +Programs is provided solely for reference purposes and may not be modified, +unless such source code is under Separate Terms permitting modification. + +Ownership + +Oracle or its licensors retain all ownership and intellectual property rights to +the Programs. + +Information Collection + +The Programs' installation and/or auto-update processes, if any, may transmit a +limited amount of data to Oracle or its service provider about those processes +to help Oracle understand and optimize them. Oracle does not associate the data +with personally identifiable information. Refer to Oracle's Privacy Policy at +www.oracle.com/privacy. + +Disclaimer of Warranties; Limitation of Liability + +THE PROGRAMS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. ORACLE FURTHER +DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +NONINFRINGEMENT. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL ORACLE BE LIABLE TO YOU FOR +DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT +LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/docs/Javadoc/apidocs/legal/dejavufonts.md b/docs/Javadoc/apidocs/legal/dejavufonts.md new file mode 100644 index 00000000..8c9e3cf3 --- /dev/null +++ b/docs/Javadoc/apidocs/legal/dejavufonts.md @@ -0,0 +1,191 @@ +## DejaVu fonts v2.37 + +### DejaVu License +
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot
+org.
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free
+. fr.
+
+TeX Gyre DJV Math
+-----------------
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+
+Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski
+(on behalf of TeX users groups) are in public domain.
+
+Letters imported from Euler Fraktur from AMSfonts are (c) American
+Mathematical Society (see below).
+Bitstream Vera Fonts Copyright
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera
+is a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation
+files (the "Font Software"), to reproduce and distribute the Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute,
+and/or sell copies of the Font Software, and to permit persons  to whom
+the Font Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be
+included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional
+glyphs or characters may be added to the Fonts, only if the fonts are
+renamed
+to names not containing either the words "Bitstream" or the word "Vera".
+
+This License becomes null and void to the extent applicable to Fonts or
+Font Software
+that has been modified and is distributed under the "Bitstream Vera"
+names.
+
+The Font Software may be sold as part of a larger software package but
+no copy
+of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL,
+SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
+ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
+INABILITY TO USE
+THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+Except as contained in this notice, the names of GNOME, the GNOME
+Foundation,
+and Bitstream Inc., shall not be used in advertising or otherwise to promote
+the sale, use or other dealings in this Font Software without prior written
+authorization from the GNOME Foundation or Bitstream Inc., respectively.
+For further information, contact: fonts at gnome dot org.
+
+AMSFonts (v. 2.2) copyright
+
+The PostScript Type 1 implementation of the AMSFonts produced by and
+previously distributed by Blue Sky Research and Y&Y, Inc. are now freely
+available for general use. This has been accomplished through the
+cooperation
+of a consortium of scientific publishers with Blue Sky Research and Y&Y.
+Members of this consortium include:
+
+Elsevier Science IBM Corporation Society for Industrial and Applied
+Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS)
+
+In order to assure the authenticity of these fonts, copyright will be
+held by
+the American Mathematical Society. This is not meant to restrict in any way
+the legitimate use of the fonts, such as (but not limited to) electronic
+distribution of documents containing these fonts, inclusion of these fonts
+into other public domain or commercial font collections or computer
+applications, use of the outline data to create derivative fonts and/or
+faces, etc. However, the AMS does require that the AMS copyright notice be
+removed from any derivative versions of the fonts which have been altered in
+any way. In addition, to ensure the fidelity of TeX documents using Computer
+Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces,
+has requested that any alterations which yield different font metrics be
+given a different name.
+
+
diff --git a/docs/Javadoc/apidocs/legal/jquery.md b/docs/Javadoc/apidocs/legal/jquery.md new file mode 100644 index 00000000..a763ec6f --- /dev/null +++ b/docs/Javadoc/apidocs/legal/jquery.md @@ -0,0 +1,26 @@ +## jQuery v3.7.1 + +### jQuery License +``` +jQuery v 3.7.1 +Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` diff --git a/docs/Javadoc/apidocs/legal/jqueryUI.md b/docs/Javadoc/apidocs/legal/jqueryUI.md new file mode 100644 index 00000000..46bfbaa5 --- /dev/null +++ b/docs/Javadoc/apidocs/legal/jqueryUI.md @@ -0,0 +1,49 @@ +## jQuery UI v1.14.1 + +### jQuery UI License +``` +Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +``` diff --git a/docs/Javadoc/apidocs/member-search-index.js b/docs/Javadoc/apidocs/member-search-index.js new file mode 100644 index 00000000..ebd9a0f1 --- /dev/null +++ b/docs/Javadoc/apidocs/member-search-index.js @@ -0,0 +1 @@ +memberSearchIndex = [{"p":"ntnu.systemutvikling.team6.service","c":"APIToDatabaseService","l":"addAPIDataToTable(List)","u":"addAPIDataToTable(java.util.List)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"addCharity(Charity)","u":"addCharity(ntnu.systemutvikling.team6.models.Charity)"},{"p":"ntnu.systemutvikling.team6.database.DAO","c":"DonationDAO","l":"addDonation(Charity, User, double)","u":"addDonation(ntnu.systemutvikling.team6.models.Charity,ntnu.systemutvikling.team6.models.user.User,double)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"DonationRegistry","l":"addDonation(Donation)","u":"addDonation(ntnu.systemutvikling.team6.models.Donation)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Inbox","l":"addMessage(Message)","u":"addMessage(ntnu.systemutvikling.team6.models.user.Message)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"UserRegistry","l":"addUser(User)","u":"addUser(ntnu.systemutvikling.team6.models.user.User)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"APICharityData(String, String, String, String, boolean)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean)","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityScraper","l":"APICharityScraper(HttpClient)","u":"%3Cinit%3E(java.net.http.HttpClient)","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"APIToDatabaseService","l":"APIToDatabaseService(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"AuthenticationService(UserSelect, UserDAO)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.Readers.UserSelect,ntnu.systemutvikling.team6.database.DAO.UserDAO)","k":"3"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"BaseController","l":"authToken","k":"1"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"BaseController","l":"authTokenisSet()"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"authTokenisSet()"},{"p":"ntnu.systemutvikling.team6.controller","c":"AvailableOrganizationController","l":"AvailableOrganizationController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"BaseController","l":"BaseController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"CategorySelect","l":"CategorySelect(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"changeLanguage(Language)","u":"changeLanguage(ntnu.systemutvikling.team6.models.user.Language)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Role","l":"CHARITY_USER","k":"0"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"Charity(String, String, Boolean, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.Boolean,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"Charity(String, String, String, boolean, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,boolean,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"Charity(String, String, String, String, String, boolean, String, String, String, byte[])","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,java.lang.String,java.lang.String,java.lang.String,byte[])","k":"3"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"CharityPageController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"CharityRegistry()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"CharitySelect","l":"CharitySelect(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"CharityService","l":"CharityService()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityScraper","l":"checkConnection()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"checkPassword(String)","u":"checkPassword(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"closeDriver()"},{"p":"ntnu.systemutvikling.team6.scraper","c":"LogoDownloader","l":"convertBlobToPNG(byte[], String)","u":"convertBlobToPNG(byte[],java.lang.String)","k":"6"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseSetup","l":"createTables()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"createWait()"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseConnection","l":"DatabaseConnection()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseConnection","l":"DatabaseConnection(String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseSetup","l":"DatabaseSetup(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"Donate(ActionEvent)","u":"Donate(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"Donation(double, LocalDate, Charity, User)","u":"%3Cinit%3E(double,java.time.LocalDate,ntnu.systemutvikling.team6.models.Charity,ntnu.systemutvikling.team6.models.user.User)","k":"3"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"Donation(String, double, LocalDate, Charity, User, boolean)","u":"%3Cinit%3E(java.lang.String,double,java.time.LocalDate,ntnu.systemutvikling.team6.models.Charity,ntnu.systemutvikling.team6.models.user.User,boolean)","k":"3"},{"p":"ntnu.systemutvikling.team6.database.DAO","c":"DonationDAO","l":"DonationDAO(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"DonationPageController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"DonationRegistry","l":"DonationRegistry()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"DonationSelect","l":"DonationSelect(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"DonationService","l":"DonationService()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper","c":"LogoDownloader","l":"downloadImageAsBlob(String)","u":"downloadImageAsBlob(java.lang.String)","k":"6"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Language","l":"ENGLISH","k":"0"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"Feedback(String, User, String, LocalDate)","u":"%3Cinit%3E(java.lang.String,ntnu.systemutvikling.team6.models.user.User,java.lang.String,java.time.LocalDate)","k":"3"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"Feedback(User, String)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.models.user.User,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"FeedbackService","l":"FeedbackService()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"findCharityByOrgnumber(String)","u":"findCharityByOrgnumber(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"findCharityByUUID(UUID)","u":"findCharityByUUID(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"DonationRegistry","l":"findDonationById(UUID)","u":"findDonationById(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"findElement(By)","u":"findElement(org.openqa.selenium.By)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"findElements(By)","u":"findElements(org.openqa.selenium.By)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Inbox","l":"findMessageById(UUID)","u":"findMessageById(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"UserRegistry","l":"findUserById(UUID)","u":"findUserById(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"FrontpageController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper","c":"FullCharityScrape","l":"FullCharityScrape()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"getAllCharities()"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"DonationRegistry","l":"getAllDonations()"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"UserRegistry","l":"getAllUsers()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getAmount()"},{"p":"ntnu.systemutvikling.team6.scraper","c":"FullCharityScrape","l":"getAPIAndURLCharityData()"},{"p":"ntnu.systemutvikling.team6.scraper","c":"FullCharityScrape","l":"getAPIScraper()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"getCategories()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"CategorySelect","l":"getCategoriesFromDB()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getCategory()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"CharitySelect","l":"getCharitiesFromDB()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getCharity()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getCharityId()"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"getComment()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"getContent()"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"getCurrentUser()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getDate()"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"getDate()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getDescription()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"getDescription()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getDisplayName()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"DonationSelect","l":"getDonationFromDB()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getDonationID()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"getDonor()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getEmail()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"CharitySelect","l":"getFeedbackforCharityUUID(String)","u":"getFeedbackforCharityUUID(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"getFeedbackId()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getFeedbacks()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"getFrom()"},{"p":"ntnu.systemutvikling.team6.security","c":"PasswordHasher","l":"getHashPassword(String)","u":"getHashPassword(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"getId()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getId()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getInbox()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"getInboxForUser(String)","u":"getInboxForUser(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"getIs_pre_approved()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityScraper","l":"getJSONData()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getKeyValues()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"getKeyValues()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"getLanguage()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getLogoBlob()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getLogoURL()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"getLogoURL()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Inbox","l":"getMessages()"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseConnection","l":"getMySqlConnection()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getName()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"getName()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getOrg_number()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"getOrg_number()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getPasswordHash()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getPreApproved()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getRole()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getSettings()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"getSettingsForUser(String)","u":"getSettingsForUser(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getStatus()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"getStatus()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"getTimeAndDate()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"getTitle()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityData","l":"getUrl()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getURL()"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"getUser()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"getUserFromDBUsernameAndPassword(String, String)","u":"getUserFromDBUsernameAndPassword(java.lang.String,java.lang.String)"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"getUserFromDBUuid(String)","u":"getUserFromDBUuid(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"getUsername()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"getUsersFromDB()"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"getUUID()"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"handleCategoryFilterChange(ActionEvent)","u":"handleCategoryFilterChange(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"handleFrontSearch(ActionEvent)","u":"handleFrontSearch(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"handleHomepageClick(ActionEvent)","u":"handleHomepageClick(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"handleSearch(ActionEvent)","u":"handleSearch(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"NavbarFooterController","l":"handleSearch(ActionEvent)","u":"handleSearch(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"handleSearch(ActionEvent)","u":"handleSearch(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6","c":"HmHApplication","l":"HmHApplication()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Inbox","l":"Inbox()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6","c":"HmHApplication","l":"init()"},{"p":"ntnu.systemutvikling.team6.controller","c":"AvailableOrganizationController","l":"initialize()"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"initialize()"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"initialize()"},{"p":"ntnu.systemutvikling.team6.models","c":"Donation","l":"isAnonymous()"},{"p":"ntnu.systemutvikling.team6.models","c":"Feedback","l":"isAnonymous()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"isAnonymous()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"isLightMode()"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"BaseController","l":"isLoggedin()"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"isLoggedin()"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"isUsernameTaken(String)","u":"isUsernameTaken(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.security","c":"PasswordHasher","l":"isValidPassword(String, String)","u":"isValidPassword(java.lang.String,java.lang.String)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"LoaderScene","l":"LoaderScene()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"LoaderScene","l":"LoadScene(String, ActionEvent, Charity, String)","u":"LoadScene(java.lang.String,javafx.event.ActionEvent,ntnu.systemutvikling.team6.models.Charity,java.lang.String)","k":"6"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"login(String, String)","u":"login(java.lang.String,java.lang.String)"},{"p":"ntnu.systemutvikling.team6.scraper","c":"LogoDownloader","l":"LogoDownloader()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"logout()"},{"p":"ntnu.systemutvikling.team6","c":"Main","l":"Main()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6","c":"HmHApplication","l":"main(String[])","u":"main(java.lang.String[])","k":"6"},{"p":"ntnu.systemutvikling.team6","c":"Main","l":"main(String[])","u":"main(java.lang.String[])","k":"6"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"Message(String, UUID, String)","u":"%3Cinit%3E(java.lang.String,java.util.UUID,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Message","l":"Message(String, UUID, String, LocalDate)","u":"%3Cinit%3E(java.lang.String,java.util.UUID,java.lang.String,java.time.LocalDate)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Role","l":"NORMAL_USER","k":"0"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Language","l":"NORWEGIAN","k":"0"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"OrganizationCardController","l":"OrganizationCardController()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"APICharityScraper","l":"parseJSON(String)","u":"parseJSON(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.security","c":"PasswordHasher","l":"PasswordHasher()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"processDonation(Charity, User, double)","u":"processDonation(ntnu.systemutvikling.team6.models.Charity,ntnu.systemutvikling.team6.models.user.User,double)"},{"p":"ntnu.systemutvikling.team6.service","c":"AuthenticationService","l":"register(String, String, String, String)","u":"register(java.lang.String,java.lang.String,java.lang.String,java.lang.String)"},{"p":"ntnu.systemutvikling.team6.database.DAO","c":"UserDAO","l":"registerUser(User)","u":"registerUser(ntnu.systemutvikling.team6.models.user.User)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"removeCharity(String)","u":"removeCharity(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"CharityRegistry","l":"removeCharityUUID(UUID)","u":"removeCharityUUID(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"DonationRegistry","l":"removeDonation(UUID)","u":"removeDonation(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Inbox","l":"removeMessage(UUID)","u":"removeMessage(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"UserRegistry","l":"removeUserByUUID(UUID)","u":"removeUserByUUID(java.util.UUID)"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"scrapeCharityPage()"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"BaseController","l":"setAuthToken(AuthenticationService)","u":"setAuthToken(ntnu.systemutvikling.team6.service.AuthenticationService)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"setCategories(List)","u":"setCategories(java.util.List)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setCategory(List)","u":"setCategory(java.util.List)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"setCharity(Charity)","u":"setCharity(ntnu.systemutvikling.team6.models.Charity)"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"setCharity(Charity)","u":"setCharity(ntnu.systemutvikling.team6.models.Charity)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setDescription(String)","u":"setDescription(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"setEmail(String)","u":"setEmail(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setFeedbacks(ArrayList)","u":"setFeedbacks(java.util.ArrayList)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"setInbox(Inbox)","u":"setInbox(ntnu.systemutvikling.team6.models.user.Inbox)"},{"p":"ntnu.systemutvikling.team6.controller","c":"AvailableOrganizationController","l":"setInitialSearch(String)","u":"setInitialSearch(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setKeyValues(String)","u":"setKeyValues(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setLogoBlob(byte[])"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setLogoURL(String)","u":"setLogoURL(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"OrganizationCardController","l":"setOrganization(Charity)","u":"setOrganization(ntnu.systemutvikling.team6.models.Charity)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"setPassword(String)","u":"setPassword(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"setSettings(Settings)","u":"setSettings(ntnu.systemutvikling.team6.models.user.Settings)"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"Settings()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"Settings(boolean, Language, boolean)","u":"%3Cinit%3E(boolean,ntnu.systemutvikling.team6.models.user.Language,boolean)","k":"3"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setUnverified()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"setUsername(String)","u":"setUsername(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setUUIDFromString(String)","u":"setUUIDFromString(java.lang.String)"},{"p":"ntnu.systemutvikling.team6.models","c":"Charity","l":"setVerified()"},{"p":"ntnu.systemutvikling.team6","c":"HmHApplication","l":"start(Stage)","u":"start(javafx.stage.Stage)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"NavbarFooterController","l":"switchToAboutPage(ActionEvent)","u":"switchToAboutPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"AvailableOrganizationController","l":"switchToCharityPage(ActionEvent)","u":"switchToCharityPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"OrganizationCardController","l":"switchToCharityPage(ActionEvent)","u":"switchToCharityPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"switchToCharityPage(ActionEvent)","u":"switchToCharityPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"switchToCharityPage(ActionEvent)","u":"switchToCharityPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"AvailableOrganizationController","l":"switchToDonationPage(ActionEvent)","u":"switchToDonationPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"switchToDonationPage(ActionEvent)","u":"switchToDonationPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"OrganizationCardController","l":"switchToDonationPage(ActionEvent)","u":"switchToDonationPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"FrontpageController","l":"switchToDonationPage(ActionEvent)","u":"switchToDonationPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"CharityPageController","l":"switchToFrontPage(ActionEvent)","u":"switchToFrontPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"NavbarFooterController","l":"switchToFrontPage(ActionEvent)","u":"switchToFrontPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller","c":"DonationPageController","l":"switchToFrontPage(ActionEvent)","u":"switchToFrontPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"NavbarFooterController","l":"switchToLoginPage(ActionEvent)","u":"switchToLoginPage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.controller.components","c":"NavbarFooterController","l":"switchToProfilePage(ActionEvent)","u":"switchToProfilePage(javafx.event.ActionEvent)"},{"p":"ntnu.systemutvikling.team6.database","c":"DatabaseSetup","l":"testConnection()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"toggleAnonymousMode()"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Settings","l":"toggleLightMode()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"updateDescription()"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"URLCharityScraper(String)","u":"%3Cinit%3E(java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","c":"URLCharityScraper","l":"URLCharityScraper(String, WebDriver)","u":"%3Cinit%3E(java.lang.String,org.openqa.selenium.WebDriver)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"User(String, String, String, String, Role, Settings, Inbox)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,ntnu.systemutvikling.team6.models.user.Role,ntnu.systemutvikling.team6.models.user.Settings,ntnu.systemutvikling.team6.models.user.Inbox)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"User","l":"User(String, String, String, String, String, String)","u":"%3Cinit%3E(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)","k":"3"},{"p":"ntnu.systemutvikling.team6.database.DAO","c":"UserDAO","l":"UserDAO(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.registry","c":"UserRegistry","l":"UserRegistry()","u":"%3Cinit%3E()","k":"3"},{"p":"ntnu.systemutvikling.team6.database.Readers","c":"UserSelect","l":"UserSelect(DatabaseConnection)","u":"%3Cinit%3E(ntnu.systemutvikling.team6.database.DatabaseConnection)","k":"3"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Language","l":"valueOf(String)","u":"valueOf(java.lang.String)","k":"6"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Role","l":"valueOf(String)","u":"valueOf(java.lang.String)","k":"6"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Language","l":"values()","k":"6"},{"p":"ntnu.systemutvikling.team6.models.user","c":"Role","l":"values()","k":"6"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/Javadoc/apidocs/module-search-index.js b/docs/Javadoc/apidocs/module-search-index.js new file mode 100644 index 00000000..0d59754f --- /dev/null +++ b/docs/Javadoc/apidocs/module-search-index.js @@ -0,0 +1 @@ +moduleSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/HmHApplication.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/HmHApplication.html new file mode 100644 index 00000000..42309199 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/HmHApplication.html @@ -0,0 +1,230 @@ + + + + +HmHApplication (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class HmHApplication

+
+
java.lang.Object +
javafx.application.Application +
ntnu.systemutvikling.team6.HmHApplication
+
+
+
+
+
+
public class HmHApplication +extends javafx.application.Application
+
+
+
+
    + +
  • +
    +

    Nested Class Summary

    +
    +

    Nested classes/interfaces inherited from class javafx.application.Application

    +javafx.application.Application.Parameters
    +
    +
  • + +
  • +
    +

    Field Summary

    +
    +

    Fields inherited from class javafx.application.Application

    +STYLESHEET_CASPIAN, STYLESHEET_MODENA
    +
    +
  • + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    + +
     
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    void
    + +
     
    +
    static void
    +
    main(String[] args)
    +
     
    +
    void
    +
    start(javafx.stage.Stage stage)
    +
     
    +
    +
    +
    +
    +

    Methods inherited from class javafx.application.Application

    +getHostServices, getParameters, getUserAgentStylesheet, launch, launch, notifyPreloader, setUserAgentStylesheet, stop
    +
    +

    Methods inherited from class Object

    +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      HmHApplication

      +
      +
      public HmHApplication()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      start

      +
      +
      public void start(javafx.stage.Stage stage) + throws Exception
      +
      +
      Specified by:
      +
      start in class javafx.application.Application
      +
      Throws:
      +
      Exception
      +
      +
      +
      +
    • +
    • +
      +

      init

      +
      +
      public void init()
      +
      +
      Overrides:
      +
      init in class javafx.application.Application
      +
      +
      +
      +
    • +
    • +
      +

      main

      +
      +
      public static void main(String[] args)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/Main.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/Main.html new file mode 100644 index 00000000..10ad40e8 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/Main.html @@ -0,0 +1,170 @@ + + + + +Main (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Main

+
+
java.lang.Object +
ntnu.systemutvikling.team6.Main
+
+
+
+
+
public class Main +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Main

      +
      +
      public Main()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      main

      +
      +
      public static void main(String[] args)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/HmHApplication.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/HmHApplication.html new file mode 100644 index 00000000..f2c98c00 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/HmHApplication.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.HmHApplication (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.HmHApplication

+
+No usage of ntnu.systemutvikling.team6.HmHApplication + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/Main.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/Main.html new file mode 100644 index 00000000..9d6a1ad0 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/class-use/Main.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.Main (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.Main

+
+No usage of ntnu.systemutvikling.team6.Main + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.html new file mode 100644 index 00000000..ab4fecec --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.html @@ -0,0 +1,263 @@ + + + + +AvailableOrganizationController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class AvailableOrganizationController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.components.BaseController +
ntnu.systemutvikling.team6.controller.AvailableOrganizationController
+
+
+
+
+
All Implemented Interfaces:
+
NavbarFooterController
+
+
+
+
public class AvailableOrganizationController +extends BaseController +implements NavbarFooterController
+
This controller represents the available organization page, where the user can search for a +charity and choose to donate to it. It also has a button to return to the front page. The user +can search for a charity by typing in the search field, and the charities that match the search +query will be displayed. The user can click on a charity to see more details about it, or click +on the featured charity to see more details about it. The user can also switch to the charity +page or donation page for the selected charity.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      AvailableOrganizationController

      +
      +
      public AvailableOrganizationController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      initialize

      +
      +
      public void initialize()
      +
      This method is used to initialize the available organization page. It retrieves all charities +from the database and sets up a listener on the search field to filter the charities based on +the user's input. It also clears the cards container to prepare for displaying the filtered +charities. The method is called automatically when the page is loaded, and it sets up the +initial state of the page.
      +
      +
      +
    • +
    • +
      +

      setInitialSearch

      +
      +
      public void setInitialSearch(String query)
      +
      This method is used to set the initial search query in the search field.
      +
      +
      Parameters:
      +
      query - is the initial search query.
      +
      +
      +
      +
    • +
    • +
      +

      switchToCharityPage

      +
      +
      public void switchToCharityPage(javafx.event.ActionEvent event)
      +
      This method is used to switch to the charity page for the selected charity.
      +
      +
      Parameters:
      +
      event - action event from button click
      +
      +
      +
      +
    • +
    • +
      +

      switchToDonationPage

      +
      +
      public void switchToDonationPage(javafx.event.ActionEvent event)
      +
      This method is used to switch to the donation page.
      +
      +
      Parameters:
      +
      event - action event from button click
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/CharityPageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/CharityPageController.html new file mode 100644 index 00000000..dcc3656d --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/CharityPageController.html @@ -0,0 +1,286 @@ + + + + +CharityPageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class CharityPageController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.CharityPageController
+
+
+
+
+
public class CharityPageController +extends Object
+
This controller represents the charity page, where the user can read about the charity and choose +to donate to it. It also has a button to return to the front page.
+
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    + +
     
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    void
    +
    handleHomepageClick(javafx.event.ActionEvent event)
    +
    +
    Opens OS default webbrowser and loads the url of the charity on click.
    +
    +
    void
    +
    handleSearch(javafx.event.ActionEvent event)
    +
    +
    This method is used to search for charities based on the input in the search field.
    +
    +
    void
    + +
     
    +
    void
    +
    setCategories(List<String> categories)
    +
    +
    Takes a list of categories for the charities and populates a scroll pane with labels containing +the charities.
    +
    +
    void
    + +
    +
    This method is used to set the charity that is being displayed on the page.
    +
    +
    void
    +
    switchToDonationPage(javafx.event.ActionEvent event)
    +
    +
    This method is used to switch to the donation page.
    +
    +
    void
    +
    switchToFrontPage(javafx.event.ActionEvent event)
    +
     
    +
    +
    +
    +
    +

    Methods inherited from class Object

    +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CharityPageController

      +
      +
      public CharityPageController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      initialize

      +
      +
      public void initialize()
      +
      +
      +
    • +
    • +
      +

      setCharity

      +
      +
      public void setCharity(Charity charity)
      +
      This method is used to set the charity that is being displayed on the page. It also updates the +labels with the charity's name and description. It acts like an initializer for the charity +page, since the charity is not known until the user clicks on a charity from the front page. +Param charity is the charity that is being displayed on the page, AND is called on from the +front page when the user clicks on a charity, to set the charity that is being displayed on the +page.
      +
      +
      Parameters:
      +
      charity - the charity to be displayed
      +
      +
      +
      +
    • +
    • +
      +

      switchToDonationPage

      +
      +
      public void switchToDonationPage(javafx.event.ActionEvent event)
      +
      This method is used to switch to the donation page.
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      switchToFrontPage

      +
      +
      public void switchToFrontPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      handleSearch

      +
      +
      public void handleSearch(javafx.event.ActionEvent event)
      +
      This method is used to search for charities based on the input in the search field.
      +
      +
      Parameters:
      +
      event - is the event that triggered the search.
      +
      +
      +
      +
    • +
    • +
      +

      handleHomepageClick

      +
      +
      public void handleHomepageClick(javafx.event.ActionEvent event)
      +
      Opens OS default webbrowser and loads the url of the charity on click.
      +
      +
      Parameters:
      +
      event - the onclick event
      +
      +
      +
      +
    • +
    • +
      +

      setCategories

      +
      +
      public void setCategories(List<String> categories)
      +
      Takes a list of categories for the charities and populates a scroll pane with labels containing +the charities.
      +
      +
      Parameters:
      +
      categories - the list of categories for the charity
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/DonationPageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/DonationPageController.html new file mode 100644 index 00000000..838e71a9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/DonationPageController.html @@ -0,0 +1,285 @@ + + + + +DonationPageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DonationPageController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.DonationPageController
+
+
+
+
+
public class DonationPageController +extends Object
+
This controller represents the donation page, where the user can enter a donation amount and +confirm their donation to the charity. It also has a button to return to the front page.
+
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    + +
     
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    void
    +
    Donate(javafx.event.ActionEvent event)
    +
    +
    This method is used to process the donation when the user clicks the donate button.
    +
    +
    void
    +
    handleSearch(javafx.event.ActionEvent event)
    +
    +
    This method is used to handle the search action when the user clicks the search button.
    +
    +
    void
    +
    processDonation(Charity charity, + User user, + double amount)
    +
    +
    Invoke DAO object to add the donation to the database.
    +
    +
    void
    + +
    +
    Initialize method for the donation page.
    +
    +
    void
    +
    switchToCharityPage(javafx.event.ActionEvent event)
    +
    +
    This method is used to switch back to the Donation page when the user clicks the back button.
    +
    +
    void
    +
    switchToFrontPage(javafx.event.ActionEvent event)
    +
    +
    This method is used to switch back to the front page when the user clicks the back button.
    +
    +
    +
    +
    +
    +

    Methods inherited from class Object

    +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DonationPageController

      +
      +
      public DonationPageController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      setCharity

      +
      +
      public void setCharity(Charity charity)
      +
      Initialize method for the donation page. Sets the charity name label to the name of the charity +that is being donated to. The charity is set from the original page it was called from when the +user clicks on the donate button, and is passed as a parameter to this method.
      +
      +
      Parameters:
      +
      charity -
      +
      +
      +
      +
    • +
    • +
      +

      switchToFrontPage

      +
      +
      public void switchToFrontPage(javafx.event.ActionEvent event)
      +
      This method is used to switch back to the front page when the user clicks the back button.
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      switchToCharityPage

      +
      +
      public void switchToCharityPage(javafx.event.ActionEvent event)
      +
      This method is used to switch back to the Donation page when the user clicks the back button.
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      Donate

      +
      +
      public void Donate(javafx.event.ActionEvent event)
      +
      This method is used to process the donation when the user clicks the donate button. Checks if +the input is valid and displays appropriate error messages if it is not. If the input is valid, +it shows a confirmation dialog to the user. Shows a confirmation dialog. If the user confirms, +the donation is processed and the user is taken back to the front page.
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      processDonation

      +
      +
      public void processDonation(Charity charity, + User user, + double amount)
      +
      Invoke DAO object to add the donation to the database. This method is called from the Donate +method after the user confirms their donation.
      +
      +
      Parameters:
      +
      charity -
      +
      amount -
      +
      +
      +
      +
    • +
    • +
      +

      handleSearch

      +
      +
      public void handleSearch(javafx.event.ActionEvent event)
      +
      This method is used to handle the search action when the user clicks the search button.
      +
      +
      Parameters:
      +
      event - is the event that triggered the search.
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/FrontpageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/FrontpageController.html new file mode 100644 index 00000000..69a86741 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/FrontpageController.html @@ -0,0 +1,298 @@ + + + + +FrontpageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class FrontpageController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.components.BaseController +
ntnu.systemutvikling.team6.controller.FrontpageController
+
+
+
+
+
All Implemented Interfaces:
+
NavbarFooterController
+
+
+
+
public class FrontpageController +extends BaseController +implements NavbarFooterController
+
Landing page's controller. This is the first page the user sees when they open the application. +It displays a random featured charity, some statistics about the charities and donations, and a +list of all charities in the database. The user can click on a charity to see more details about +it, or click on the featured charity to see more details about it. It also has buttons to switch +to the charity page and the donation page for the featured charity
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      FrontpageController

      +
      +
      public FrontpageController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      authTokenisSet

      +
      +
      protected void authTokenisSet()
      +
      +
      Overrides:
      +
      authTokenisSet in class BaseController
      +
      +
      +
      +
    • +
    • +
      +

      initialize

      +
      +
      public void initialize()
      +
      Initialize method for the front page. This method is called when the front page is loaded. It +retrieves the list of charities and donations from the database. The list of charities is +displayed as a list of cards, where each card represents a charity from the +Innsamlingskontrollen. A random charity is selected to be featured on the page, and its name +and description are displayed in the carousel section. The total number of charities, total +amount of donations, and percentage of pre-approved charities are also displayed on the page.
      +
      +
      +
    • +
    • +
      +

      switchToCharityPage

      +
      +
      public void switchToCharityPage(javafx.event.ActionEvent event)
      +
      This method is used to switch to the charity page for the selected charity
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      switchToDonationPage

      +
      +
      public void switchToDonationPage(javafx.event.ActionEvent event)
      +
      This method is used to switch to the donation page for the selected charity.
      +
      +
      Parameters:
      +
      event -
      +
      +
      +
      +
    • +
    • +
      +

      handleCategoryFilterChange

      +
      +
      public void handleCategoryFilterChange(javafx.event.ActionEvent event)
      +
      This method is used to filter the charities based on the selected filters.
      +
      +
      Parameters:
      +
      event - is the event that triggered the filter.
      +
      +
      +
      +
    • +
    • +
      +

      handleFrontSearch

      +
      +
      public void handleFrontSearch(javafx.event.ActionEvent event)
      +
      This method is used to search for charities based on the input in the search field.
      +
      +
      Parameters:
      +
      event - is the event that triggered the search.
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/AvailableOrganizationController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/AvailableOrganizationController.html new file mode 100644 index 00000000..be977d60 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/AvailableOrganizationController.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.AvailableOrganizationController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.AvailableOrganizationController

+
+No usage of ntnu.systemutvikling.team6.controller.AvailableOrganizationController + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/CharityPageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/CharityPageController.html new file mode 100644 index 00000000..3c20308a --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/CharityPageController.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.CharityPageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.CharityPageController

+
+No usage of ntnu.systemutvikling.team6.controller.CharityPageController + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/DonationPageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/DonationPageController.html new file mode 100644 index 00000000..94336983 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/DonationPageController.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.DonationPageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.DonationPageController

+
+No usage of ntnu.systemutvikling.team6.controller.DonationPageController + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/FrontpageController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/FrontpageController.html new file mode 100644 index 00000000..cbccec9c --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/class-use/FrontpageController.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.FrontpageController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.FrontpageController

+
+No usage of ntnu.systemutvikling.team6.controller.FrontpageController + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/BaseController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/BaseController.html new file mode 100644 index 00000000..d5fd402f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/BaseController.html @@ -0,0 +1,235 @@ + + + + +BaseController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class BaseController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.components.BaseController
+
+
+
+
Direct Known Subclasses:
+
AvailableOrganizationController, FrontpageController
+
+
+
+
public abstract class BaseController +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Field Details

    + +
    +
  • + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      BaseController

      +
      +
      public BaseController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      setAuthToken

      +
      +
      public void setAuthToken(AuthenticationService authToken)
      +
      +
      +
    • +
    • +
      +

      authTokenisSet

      +
      +
      protected void authTokenisSet()
      +
      +
      +
    • +
    • +
      +

      isLoggedin

      +
      +
      protected boolean isLoggedin()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/LoaderScene.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/LoaderScene.html new file mode 100644 index 00000000..55eb4f45 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/LoaderScene.html @@ -0,0 +1,191 @@ + + + + +LoaderScene (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class LoaderScene

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.components.LoaderScene
+
+
+
+
+
public class LoaderScene +extends Object
+
This class is a utility class that is used to load different scenes in the application. For now, +It is used to switch between the front page, charity page, and donation page. It takes care of +loading the FXML file, setting the controller, and switching the scene.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      LoaderScene

      +
      +
      public LoaderScene()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      LoadScene

      +
      +
      public static void LoadScene(String sceneName, + javafx.event.ActionEvent event, + Charity charity, + String query)
      +
      When going to a new scene, this method is called to load the new scene. It takes the name of +the scene to load, the event that triggered the scene change, and the charity that is being +passed to the new scene (if applicable). It loads the FXML file for the new scene, sets the +controller, and switches the scene.
      +
      +
      Parameters:
      +
      sceneName -
      +
      event -
      +
      charity -
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/NavbarFooterController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/NavbarFooterController.html new file mode 100644 index 00000000..4cce3b20 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/NavbarFooterController.html @@ -0,0 +1,180 @@ + + + + +NavbarFooterController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Interface NavbarFooterController

+
+
+
+
All Known Implementing Classes:
+
AvailableOrganizationController, FrontpageController
+
+
+
+
public interface NavbarFooterController
+
+
+
+
    + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    default void
    +
    handleSearch(javafx.event.ActionEvent event)
    +
     
    +
    default void
    +
    switchToAboutPage(javafx.event.ActionEvent event)
    +
     
    +
    default void
    +
    switchToFrontPage(javafx.event.ActionEvent event)
    +
     
    +
    default void
    +
    switchToLoginPage(javafx.event.ActionEvent event)
    +
     
    +
    default void
    +
    switchToProfilePage(javafx.event.ActionEvent event)
    +
     
    +
    +
    +
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      switchToFrontPage

      +
      +
      default void switchToFrontPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      switchToAboutPage

      +
      +
      default void switchToAboutPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      switchToProfilePage

      +
      +
      default void switchToProfilePage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      handleSearch

      +
      +
      default void handleSearch(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      switchToLoginPage

      +
      +
      default void switchToLoginPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.html new file mode 100644 index 00000000..5e359d0f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.html @@ -0,0 +1,197 @@ + + + + +OrganizationCardController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class OrganizationCardController

+
+
java.lang.Object +
ntnu.systemutvikling.team6.controller.components.OrganizationCardController
+
+
+
+
+
public class OrganizationCardController +extends Object
+
This controller represents the organization card that is displayed on the front page and is +looped upon in FronpageController. It is used to display the name and description of a charity, +and to switch to the charity page or donation page when the user clicks on the card.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      OrganizationCardController

      +
      +
      public OrganizationCardController()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      setOrganization

      +
      +
      public void setOrganization(Charity charity)
      +
      +
      +
    • +
    • +
      +

      switchToCharityPage

      +
      +
      public void switchToCharityPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    • +
      +

      switchToDonationPage

      +
      +
      public void switchToDonationPage(javafx.event.ActionEvent event)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/BaseController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/BaseController.html new file mode 100644 index 00000000..eecd4699 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/BaseController.html @@ -0,0 +1,98 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.components.BaseController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.components.BaseController

+
+
Packages that use BaseController
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/LoaderScene.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/LoaderScene.html new file mode 100644 index 00000000..73d6c2d9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/LoaderScene.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.components.LoaderScene (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.components.LoaderScene

+
+No usage of ntnu.systemutvikling.team6.controller.components.LoaderScene + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/NavbarFooterController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/NavbarFooterController.html new file mode 100644 index 00000000..1a39dc02 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/NavbarFooterController.html @@ -0,0 +1,98 @@ + + + + +Uses of Interface ntnu.systemutvikling.team6.controller.components.NavbarFooterController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Interface
ntnu.systemutvikling.team6.controller.components.NavbarFooterController

+
+
Packages that use NavbarFooterController
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/OrganizationCardController.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/OrganizationCardController.html new file mode 100644 index 00000000..4e2b70ce --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/class-use/OrganizationCardController.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.controller.components.OrganizationCardController (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.controller.components.OrganizationCardController

+
+No usage of ntnu.systemutvikling.team6.controller.components.OrganizationCardController + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-summary.html new file mode 100644 index 00000000..3891b010 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-summary.html @@ -0,0 +1,115 @@ + + + + +ntnu.systemutvikling.team6.controller.components (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.controller.components

+
+
+
+
package ntnu.systemutvikling.team6.controller.components
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-tree.html new file mode 100644 index 00000000..a71af992 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-tree.html @@ -0,0 +1,86 @@ + + + + +ntnu.systemutvikling.team6.controller.components Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.controller.components

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+
+

Interface Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-use.html new file mode 100644 index 00000000..d5b17f06 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/components/package-use.html @@ -0,0 +1,88 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.controller.components (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.controller.components

+
+ +
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-summary.html new file mode 100644 index 00000000..25346bb7 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-summary.html @@ -0,0 +1,131 @@ + + + + +ntnu.systemutvikling.team6.controller (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.controller

+
+
+
+
package ntnu.systemutvikling.team6.controller
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-tree.html new file mode 100644 index 00000000..20ea3123 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-tree.html @@ -0,0 +1,85 @@ + + + + +ntnu.systemutvikling.team6.controller Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.controller

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-use.html new file mode 100644 index 00000000..7d6388cf --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/controller/package-use.html @@ -0,0 +1,65 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.controller (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.controller

+
+No usage of ntnu.systemutvikling.team6.controller + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/DonationDAO.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/DonationDAO.html new file mode 100644 index 00000000..b5b2eb63 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/DonationDAO.html @@ -0,0 +1,186 @@ + + + + +DonationDAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DonationDAO

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.DAO.DonationDAO
+
+
+
+
+
public class DonationDAO +extends Object
+
This class is responsible for sending concurrent information about the donation to the Donation +Database. Usally called from the DonationPageController, where the user confirms their donation.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    + +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      addDonation

      +
      +
      public void addDonation(Charity charity, + User user, + double amount)
      +
      Gets the total ammount of donations for a given charity, and sends it to the database throught +MySQL.
      +
      +
      Parameters:
      +
      charity -
      +
      amount -
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/UserDAO.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/UserDAO.html new file mode 100644 index 00000000..71fd6fe1 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/UserDAO.html @@ -0,0 +1,187 @@ + + + + +UserDAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class UserDAO

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.DAO.UserDAO
+
+
+
+
+
public class UserDAO +extends Object
+
This class is responsible for sending concurrent information about the user to the User database, +and user settings to the settings database.
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    + +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      registerUser

      +
      +
      public boolean registerUser(User user)
      +
      Gets the user and settings information and sends it to the database through MySQL.
      +
      +
      Parameters:
      +
      user - the user to be saved in the database.
      +
      Returns:
      +
      true or false based on if the register is a success or not
      +
      Throws:
      +
      RuntimeException - if a database error occurs during the operation
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/DonationDAO.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/DonationDAO.html new file mode 100644 index 00000000..3ee95d2c --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/DonationDAO.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.DAO.DonationDAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.DAO.DonationDAO

+
+No usage of ntnu.systemutvikling.team6.database.DAO.DonationDAO + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/UserDAO.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/UserDAO.html new file mode 100644 index 00000000..68f72ead --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/class-use/UserDAO.html @@ -0,0 +1,93 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.DAO.UserDAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.DAO.UserDAO

+
+
Packages that use UserDAO
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-summary.html new file mode 100644 index 00000000..4406dbf6 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-summary.html @@ -0,0 +1,112 @@ + + + + +ntnu.systemutvikling.team6.database.DAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.database.DAO

+
+
+
+
package ntnu.systemutvikling.team6.database.DAO
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-tree.html new file mode 100644 index 00000000..246482bf --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-tree.html @@ -0,0 +1,79 @@ + + + + +ntnu.systemutvikling.team6.database.DAO Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.database.DAO

+
+Package Hierarchies: + +
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • ntnu.systemutvikling.team6.database.DAO.DonationDAO
    • +
    • ntnu.systemutvikling.team6.database.DAO.UserDAO
    • +
    +
  • +
+
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-use.html new file mode 100644 index 00000000..54cd1292 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DAO/package-use.html @@ -0,0 +1,89 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.database.DAO (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.database.DAO

+
+ +
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseConnection.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseConnection.html new file mode 100644 index 00000000..0f7de35b --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseConnection.html @@ -0,0 +1,220 @@ + + + + +DatabaseConnection (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DatabaseConnection

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.DatabaseConnection
+
+
+
+
+
public class DatabaseConnection +extends Object
+
Represents a reusable database connection through enviroment variables.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DatabaseConnection

      +
      +
      public DatabaseConnection()
      +
      Constructs a new DatabaseConnection using database credentials retrieved from system +environment variables.
      +
      +
      Throws:
      +
      IllegalStateException - if either databaseURL, username, or password is null or + blank
      +
      +
      +
      +
    • +
    • +
      +

      DatabaseConnection

      +
      +
      public DatabaseConnection(String databaseURL, + String username, + String password)
      +
      Constructs a new DatabaseConnection using database credentials + +

      Used primarily for JUnit tests. Production should use the constructor using environment +variables.

      +
      +
      Parameters:
      +
      databaseURL - the url to the database
      +
      username - the username used to log in to the database
      +
      password - the password used to log in to the database
      +
      Throws:
      +
      IllegalArgumentException - if databaseURL, username, or password is null or blank
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getMySqlConnection

      +
      +
      public Connection getMySqlConnection() + throws SQLException
      +
      Creates and returns a new MySQL database connection.
      +
      +
      Returns:
      +
      a Connection to the database
      +
      Throws:
      +
      SQLException - if the connection cannot be established
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseSetup.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseSetup.html new file mode 100644 index 00000000..90df8635 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/DatabaseSetup.html @@ -0,0 +1,205 @@ + + + + +DatabaseSetup (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DatabaseSetup

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.DatabaseSetup
+
+
+
+
+
public class DatabaseSetup +extends Object
+
Manages the Database with MySQL tables and test connection. + +

This class object is able to create MySQL to ntnu localized database and able to +testConnection to it.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DatabaseSetup

      +
      +
      public DatabaseSetup(DatabaseConnection connection)
      +
      Contractor for DatabaseManager. It uses a DatabaseConnection object that contains a connection +credentials.
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      testConnection

      +
      +
      public boolean testConnection()
      +
      Connection test for the Database. Does a simple SELECT SQL query and returns either true og and +Exception if failed
      +
      +
      Returns:
      +
      true if Sucsedd or SQLExepction if failed
      +
      +
      +
      +
    • +
    • +
      +

      createTables

      +
      +
      public void createTables()
      +
      Creates the Charities and Donations tables if they do not already exist.
      +
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while creating the table
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CategorySelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CategorySelect.html new file mode 100644 index 00000000..5fb6b1e8 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CategorySelect.html @@ -0,0 +1,188 @@ + + + + +CategorySelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class CategorySelect

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.Readers.CategorySelect
+
+
+
+
+
public class CategorySelect +extends Object
+
Data access class responsible for getting all the distinct categories from the database. + +

All queries are executed against a MySQL database via a DatabaseConnection.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CategorySelect

      +
      +
      public CategorySelect(DatabaseConnection connection)
      +
      Constructs a new CharitySelect with the given database connection.
      +
      +
      Parameters:
      +
      connection - the DatabaseConnection to use for executing queries; must not be + null
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getCategoriesFromDB

      +
      +
      public List<String> getCategoriesFromDB()
      +
      Retrieves all the categories listed in the Category table of the database.
      +
      +
      Returns:
      +
      a list of strings containing the name of the categories
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CharitySelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CharitySelect.html new file mode 100644 index 00000000..cec3e3a0 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/CharitySelect.html @@ -0,0 +1,235 @@ + + + + +CharitySelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class CharitySelect

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.Readers.CharitySelect
+
+
+
+
+
public class CharitySelect +extends Object
+
Data access class responsible for reading charity-related data from the database. + +

Provides methods to retrieve all charities (with their associated feedback and users) as well +as feedback entries for a specific charity by UUID. + +

All queries are executed against a MySQL database via a DatabaseConnection.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CharitySelect

      +
      +
      public CharitySelect(DatabaseConnection connection)
      +
      Constructs a new CharitySelect with the given database connection.
      +
      +
      Parameters:
      +
      connection - the DatabaseConnection to use for executing queries; must not be + null
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getCharitiesFromDB

      +
      +
      public CharityRegistry getCharitiesFromDB()
      +
      Retrieves all charities from the database, including their associated feedback and the users +who submitted each piece of feedback. + +

      The query performs a LEFT JOIN between the Charities, Feedback, +User, CharityVanity, and category(s) tables. Each unique charity is added once +to the registry; any feedback rows found for that charity are appended to its feedback list. + +

      Note: charities with no feedback and categories are still included in the result due to the +LEFT JOIN.

      +
      +
      Returns:
      +
      a CharityRegistry containing all charities found in the database, each + populated with its associated Feedback objects (if any)
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    • +
      +

      getFeedbackforCharityUUID

      +
      +
      public ArrayList<Feedback> getFeedbackforCharityUUID(String charity_uuid)
      +
      A helper function that retrieves all feedback entries associated with a specific charity, +identified by its UUID. Currently, has no use. + +

      Each Feedback object is populated with the associated User (without settings +or inbox data). The query uses a LEFT JOIN between the Feedback and User +tables, filtered by charity_id.

      +
      +
      Parameters:
      +
      charity_uuid - the UUID of the charity whose feedback should be retrieved; must not be + null
      +
      Returns:
      +
      an ArrayList of Feedback objects for the given charity; returns an + empty list if no feedback exists for that charity
      +
      Throws:
      +
      RuntimeException - if any exception occurs while executing the query, wrapping the + original cause
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/DonationSelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/DonationSelect.html new file mode 100644 index 00000000..a01f43a9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/DonationSelect.html @@ -0,0 +1,203 @@ + + + + +DonationSelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DonationSelect

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.Readers.DonationSelect
+
+
+
+
+
public class DonationSelect +extends Object
+
Data access class responsible for reading donation data from the database. + +

Retrieves donations along with their associated Charity by performing an INNER JOIN +between the Donations and Charities tables. Only donations with a matching +charity record are included. Donor (User) and CharityVanity details are +intentionally excluded to keep this query lightweight — join those separately if richer data is +needed. + +

Note: CharityVanity fields (name, link, description, logo) are NOT fetched here since +they live in a separate table. The Charity objects returned will only contain the core +fields present in the Charities table.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DonationSelect

      +
      +
      public DonationSelect(DatabaseConnection connection)
      +
      Constructs a new DonationSelect with the given database connection.
      +
      +
      Parameters:
      +
      connection - the DatabaseConnection to use for executing queries; must not be + null
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getDonationFromDB

      +
      +
      public DonationRegistry getDonationFromDB()
      +
      Retrieves all donations from the database, each populated with its associated Charity. + +

      The query performs an INNER JOIN between the Donations and Charities tables +on the charity UUID foreign key. Donations without a matching charity are excluded from the +result.

      +
      +
      Returns:
      +
      a DonationRegistry containing all matched donations; never null, but + may be empty if no rows are returned
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/UserSelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/UserSelect.html new file mode 100644 index 00000000..6c52e521 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/UserSelect.html @@ -0,0 +1,330 @@ + + + + +UserSelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class UserSelect

+
+
java.lang.Object +
ntnu.systemutvikling.team6.database.Readers.UserSelect
+
+
+
+
+
public class UserSelect +extends Object
+
Data access class responsible for reading user-related data from the database. + +

Provides methods to retrieve individual users (by credentials or UUID), all users, a user's +settings, and a user's inbox. Queries use LEFT JOINs across the User, Settings, +and Messages tables to assemble fully populated User objects in a single round +trip where possible.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      UserSelect

      +
      +
      public UserSelect(DatabaseConnection connection)
      +
      Constructs a new UserSelect with the given database connection.
      +
      +
      Parameters:
      +
      connection - the DatabaseConnection to use for executing queries; must not be + null
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      isUsernameTaken

      +
      +
      public boolean isUsernameTaken(String username)
      +
      +
      +
    • +
    • +
      +

      getUserFromDBUsernameAndPassword

      +
      +
      public User getUserFromDBUsernameAndPassword(String username, + String password)
      +
      Retrieves a single User from the database matching the given username and password. + +

      The password is hashed via PasswordHasher before being compared against the stored +value. If a matching user is found, their Settings (when present) and Inbox +(including any Message objects) are also populated. Returns null if no matching +user is found. + +

      Note: the current SQL query compares both parameters against +user_password; the user_name column is not yet included in the WHERE clause, which may +be a bug.

      +
      +
      Parameters:
      +
      username - the plain-text username to look up
      +
      password - the plain-text password; hashed internally before the query runs
      +
      Returns:
      +
      the matching User with settings and inbox populated, or null if no + match is found
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    • +
      +

      getUserFromDBUuid

      +
      +
      public User getUserFromDBUuid(String user_id)
      +
      Retrieves a single User from the database by their UUID. + +

      The returned user is fully populated with Settings (when present) and an Inbox containing any associated Message objects. Returns null if no user with +the given UUID exists.

      +
      +
      Parameters:
      +
      user_id - the UUID string of the user to retrieve; must not be null
      +
      Returns:
      +
      the matching User with settings and inbox populated, or null if no user + is found
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    • +
      +

      getUsersFromDB

      +
      +
      public UserRegistry getUsersFromDB()
      +
      Retrieves all users from the database, each fully populated with their Settings and +Inbox. + +

      The query LEFT JOINs User, Settings, and Messages. Multiple rows for +the same user UUID (due to multiple messages) are collapsed into a single User object +with all messages appended to its inbox.

      +
      +
      Returns:
      +
      a UserRegistry containing all users found in the database; never null, + but may be empty if no users exist
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    • +
      +

      getSettingsForUser

      +
      +
      public Settings getSettingsForUser(String user_id)
      +
      Retrieves the Settings for a specific user by their UUID. + +

      At most one row is fetched (via setMaxRows(1)). Returns null if no settings +row exists for the given user.

      +
      +
      Parameters:
      +
      user_id - the UUID string of the user whose settings should be retrieved; must not be + null
      +
      Returns:
      +
      the user's Settings, or null if none are found
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    • +
      +

      getInboxForUser

      +
      +
      public Inbox getInboxForUser(String user_id)
      +
      Retrieves the Inbox for a specific user by their UUID, populated with all of their +Message objects. + +

      Returns an empty Inbox (never null) if no messages exist for the given user.

      +
      +
      Parameters:
      +
      user_id - the UUID string of the user whose inbox should be retrieved; must not be + null
      +
      Returns:
      +
      an Inbox containing all messages for the user; empty if no messages are found
      +
      Throws:
      +
      RuntimeException - if a SQLException occurs while executing the query
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CategorySelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CategorySelect.html new file mode 100644 index 00000000..6c36972d --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CategorySelect.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.Readers.CategorySelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.Readers.CategorySelect

+
+No usage of ntnu.systemutvikling.team6.database.Readers.CategorySelect + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CharitySelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CharitySelect.html new file mode 100644 index 00000000..21b84b2d --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/CharitySelect.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.Readers.CharitySelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.Readers.CharitySelect

+
+No usage of ntnu.systemutvikling.team6.database.Readers.CharitySelect + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/DonationSelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/DonationSelect.html new file mode 100644 index 00000000..a71c25e0 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/DonationSelect.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.Readers.DonationSelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.Readers.DonationSelect

+
+No usage of ntnu.systemutvikling.team6.database.Readers.DonationSelect + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/UserSelect.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/UserSelect.html new file mode 100644 index 00000000..f5751c1d --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/class-use/UserSelect.html @@ -0,0 +1,93 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.Readers.UserSelect (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.Readers.UserSelect

+
+
Packages that use UserSelect
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-summary.html new file mode 100644 index 00000000..990198a3 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-summary.html @@ -0,0 +1,118 @@ + + + + +ntnu.systemutvikling.team6.database.Readers (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.database.Readers

+
+
+
+
package ntnu.systemutvikling.team6.database.Readers
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-tree.html new file mode 100644 index 00000000..de3ad6ea --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-tree.html @@ -0,0 +1,81 @@ + + + + +ntnu.systemutvikling.team6.database.Readers Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.database.Readers

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-use.html new file mode 100644 index 00000000..187c76a6 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/Readers/package-use.html @@ -0,0 +1,88 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.database.Readers (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.database.Readers

+
+ +
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseConnection.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseConnection.html new file mode 100644 index 00000000..52f41b3c --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseConnection.html @@ -0,0 +1,162 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.DatabaseConnection (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.DatabaseConnection

+
+
Packages that use DatabaseConnection
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseSetup.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseSetup.html new file mode 100644 index 00000000..75df7bbc --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/class-use/DatabaseSetup.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.database.DatabaseSetup (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.database.DatabaseSetup

+
+No usage of ntnu.systemutvikling.team6.database.DatabaseSetup + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-summary.html new file mode 100644 index 00000000..d42b8f49 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-summary.html @@ -0,0 +1,122 @@ + + + + +ntnu.systemutvikling.team6.database (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.database

+
+
+
+
package ntnu.systemutvikling.team6.database
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-tree.html new file mode 100644 index 00000000..b2126766 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-tree.html @@ -0,0 +1,79 @@ + + + + +ntnu.systemutvikling.team6.database Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.database

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-use.html new file mode 100644 index 00000000..7fb26777 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/database/package-use.html @@ -0,0 +1,133 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.database (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.database

+
+ + +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Charity.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Charity.html new file mode 100644 index 00000000..a09eebee --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Charity.html @@ -0,0 +1,526 @@ + + + + +Charity (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Charity

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.Charity
+
+
+
+
+
public class Charity +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Charity

      +
      +
      public Charity(String uuid, + String org_number, + Boolean is_pre_approved, + String status)
      +
      Minimal contructor JUST FOR DONATIONSSELECT. Just cause donation object needs to only contain +information about receiver Chairty and donator User, and not necessarily Urls, +logos, and etc.
      +
      +
      Parameters:
      +
      uuid - from DonationSelect
      +
      org_number - matches from DonationSelect
      +
      is_pre_approved - name matches from DonationSelect
      +
      status - name matches from DonationSelect
      +
      +
      +
      +
    • +
    • +
      +

      Charity

      +
      +
      public Charity(String org_number, + String link, + String name, + boolean is_pre_approved, + String status)
      +
      Contructor for creating a new charity. Taylored to match data given from Api. Other attributes +will just be initialized as empty
      +
      +
      Parameters:
      +
      org_number - matches from innsamlingkontrollen
      +
      name - matches from innsamlingkontrollen
      +
      is_pre_approved - name matches from innsamlingkontrollen
      +
      status - name matches from innsamlingkontrollen
      +
      +
      +
      +
    • +
    • +
      +

      Charity

      +
      +
      public Charity(String uuid, + String org_number, + String name, + String url, + String status, + boolean is_pre_approved, + String description, + String logoURL, + String keyValues, + byte[] logblob)
      +
      Contructor for creating a new charity. Taylored to match data given from DATABASE. Expects +paramaters that will fill all attributes. EXECPT for feedbacks and categories (which is done +right after).
      +
      +
      Parameters:
      +
      org_number - matches from innsamlingkontrollen
      +
      name - matches from innsamlingkontrollen
      +
      status - name matches from innsamlingkontrollen
      +
      is_pre_approved - name matches from innsamlingkontrollen
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getUUID

      +
      +
      public UUID getUUID()
      +
      Getters for the charity's attributes.
      +
      +
      +
    • +
    • +
      +

      getOrg_number

      +
      +
      public String getOrg_number()
      +
      +
      +
    • +
    • +
      +

      getStatus

      +
      +
      public String getStatus()
      +
      +
      +
    • +
    • +
      +

      getPreApproved

      +
      +
      public boolean getPreApproved()
      +
      +
      +
    • +
    • +
      +

      getFeedbacks

      +
      +
      public List<Feedback> getFeedbacks()
      +
      +
      +
    • +
    • +
      +

      getCategory

      +
      +
      public List<String> getCategory()
      +
      +
      +
    • +
    • +
      +

      getName

      +
      +
      public String getName()
      +
      +
      +
    • +
    • +
      +

      getURL

      +
      +
      public String getURL()
      +
      +
      +
    • +
    • +
      +

      getDescription

      +
      +
      public String getDescription()
      +
      +
      +
    • +
    • +
      +

      getLogoURL

      +
      +
      public String getLogoURL()
      +
      +
      +
    • +
    • +
      +

      getKeyValues

      +
      +
      public String getKeyValues()
      +
      +
      +
    • +
    • +
      +

      getLogoBlob

      +
      +
      public byte[] getLogoBlob()
      +
      +
      +
    • +
    • +
      +

      setVerified

      +
      +
      public void setVerified()
      +
      Setter for verification status. This one sets the charity as verified.
      +
      +
      +
    • +
    • +
      +

      setUnverified

      +
      +
      public void setUnverified()
      +
      Setter for verification status. This one sets the charity as unverified.
      +
      +
      +
    • +
    • +
      +

      setCategory

      +
      +
      public void setCategory(List<String> category)
      +
      Setter for categories.
      +
      +
      +
    • +
    • +
      +

      setDescription

      +
      +
      public void setDescription(String description)
      +
      Setter for description.
      +
      +
      +
    • +
    • +
      +

      setLogoURL

      +
      +
      public void setLogoURL(String url)
      +
      Setter for the URL of the charity's logo.
      +
      +
      +
    • +
    • +
      +

      setKeyValues

      +
      +
      public void setKeyValues(String values)
      +
      Setter for the charity's key values.
      +
      +
      +
    • +
    • +
      +

      setLogoBlob

      +
      +
      public void setLogoBlob(byte[] logoBlob)
      +
      Setter for the charity's logo Blob.
      +
      +
      +
    • +
    • +
      +

      setFeedbacks

      +
      +
      public void setFeedbacks(ArrayList<Feedback> feedbacks)
      +
      Setter for setting feedbacks
      +
      +
      +
    • +
    • +
      +

      setUUIDFromString

      +
      +
      public void setUUIDFromString(String uuid)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Donation.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Donation.html new file mode 100644 index 00000000..2913756d --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Donation.html @@ -0,0 +1,292 @@ + + + + +Donation (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Donation

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.Donation
+
+
+
+
+
public class Donation +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Donation

      +
      +
      public Donation(double amount, + LocalDate date, + Charity charity, + User donor)
      +
      Constructor for creating a new donation. The charityId is generated automatically using UUID. +If the donation is made anonymously, the isAnonymous parameter is set to true.
      +
      +
      Parameters:
      +
      amount -
      +
      date -
      +
      charity -
      +
      donor -
      +
      +
      +
      +
    • +
    • +
      +

      Donation

      +
      +
      public Donation(String donationId, + double amount, + LocalDate date, + Charity charity, + User donor, + boolean isAnonymous)
      +
      Constructor for creating a donation reed from the database.
      +
      +
      Parameters:
      +
      donationId - the stored UUID string for this donation; must not be null
      +
      amount - the donated amount
      +
      date - the date the donation was made; must not be null
      +
      charity - the receiving charity; must not be null
      +
      donor - the donating user, or null if anonymous
      +
      isAnonymous - whether the donation was recorded as anonymous
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      isAnonymous

      +
      +
      public boolean isAnonymous()
      +
      +
      +
    • +
    • +
      +

      getCharityId

      +
      +
      public UUID getCharityId()
      +
      +
      +
    • +
    • +
      +

      getDonationID

      +
      +
      public UUID getDonationID()
      +
      +
      +
    • +
    • +
      +

      getAmount

      +
      +
      public double getAmount()
      +
      +
      +
    • +
    • +
      +

      getDate

      +
      +
      public LocalDate getDate()
      +
      +
      +
    • +
    • +
      +

      getCharity

      +
      +
      public Charity getCharity()
      +
      +
      +
    • +
    • +
      +

      getDonor

      +
      +
      public User getDonor()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Feedback.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Feedback.html new file mode 100644 index 00000000..47053d15 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/Feedback.html @@ -0,0 +1,261 @@ + + + + +Feedback (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Feedback

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.Feedback
+
+
+
+
+
public class Feedback +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Feedback

      +
      +
      public Feedback(User user, + String comment)
      +
      Constructor for creating a new feedback now.
      +
      +
      Parameters:
      +
      user - The user who gives the feedback.
      +
      comment - The content of the feedback.
      +
      +
      +
      +
    • +
    • +
      +

      Feedback

      +
      +
      public Feedback(String feedback_id, + User user, + String feedback_comment, + LocalDate feedback_date)
      +
      Constructor for creating a new feedback, based on making a feedback previously made.
      +
      +
      Parameters:
      +
      user - The user who gives the feedback.
      +
      feedback_date - The content of the feedback.
      +
      comment - The content of the feedback.
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getFeedbackId

      +
      +
      public UUID getFeedbackId()
      +
      Getters for the feedback's attributes.
      +
      +
      Returns:
      +
      The feedback's attributes.
      +
      +
      +
      +
    • +
    • +
      +

      getComment

      +
      +
      public String getComment()
      +
      +
      +
    • +
    • +
      +

      getDate

      +
      +
      public LocalDate getDate()
      +
      +
      +
    • +
    • +
      +

      getUser

      +
      +
      public User getUser()
      +
      +
      +
    • +
    • +
      +

      isAnonymous

      +
      +
      public boolean isAnonymous()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Charity.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Charity.html new file mode 100644 index 00000000..13a0c937 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Charity.html @@ -0,0 +1,239 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.Charity (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.Charity

+
+
Packages that use Charity
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Donation.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Donation.html new file mode 100644 index 00000000..aa8a17fb --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Donation.html @@ -0,0 +1,102 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.Donation (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.Donation

+
+
Packages that use Donation
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Feedback.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Feedback.html new file mode 100644 index 00000000..7a105e45 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/class-use/Feedback.html @@ -0,0 +1,120 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.Feedback (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.Feedback

+
+
Packages that use Feedback
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-summary.html new file mode 100644 index 00000000..d2e3b881 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-summary.html @@ -0,0 +1,120 @@ + + + + +ntnu.systemutvikling.team6.models (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.models

+
+
+
+
package ntnu.systemutvikling.team6.models
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-tree.html new file mode 100644 index 00000000..9cce093c --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-tree.html @@ -0,0 +1,80 @@ + + + + +ntnu.systemutvikling.team6.models Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.models

+
+Package Hierarchies: + +
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • ntnu.systemutvikling.team6.models.Charity
    • +
    • ntnu.systemutvikling.team6.models.Donation
    • +
    • ntnu.systemutvikling.team6.models.Feedback
    • +
    +
  • +
+
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-use.html new file mode 100644 index 00000000..e9f1b429 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/package-use.html @@ -0,0 +1,168 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.models (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.models

+
+ + +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/CharityRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/CharityRegistry.html new file mode 100644 index 00000000..1b5206ab --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/CharityRegistry.html @@ -0,0 +1,230 @@ + + + + +CharityRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class CharityRegistry

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.registry.CharityRegistry
+
+
+
+
+
public class CharityRegistry +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CharityRegistry

      +
      +
      public CharityRegistry()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getAllCharities

      +
      +
      public List<Charity> getAllCharities()
      +
      +
      +
    • +
    • +
      +

      findCharityByOrgnumber

      +
      +
      public Optional<Charity> findCharityByOrgnumber(String org_number)
      +
      +
      +
    • +
    • +
      +

      findCharityByUUID

      +
      +
      public Optional<Charity> findCharityByUUID(UUID uuid)
      +
      +
      +
    • +
    • +
      +

      addCharity

      +
      +
      public void addCharity(Charity charity)
      +
      +
      +
    • +
    • +
      +

      removeCharity

      +
      +
      public boolean removeCharity(String org_number)
      +
      +
      +
    • +
    • +
      +

      removeCharityUUID

      +
      +
      public boolean removeCharityUUID(UUID uuid)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/DonationRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/DonationRegistry.html new file mode 100644 index 00000000..a1748456 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/DonationRegistry.html @@ -0,0 +1,206 @@ + + + + +DonationRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DonationRegistry

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.registry.DonationRegistry
+
+
+
+
+
public class DonationRegistry +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DonationRegistry

      +
      +
      public DonationRegistry()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getAllDonations

      +
      +
      public List<Donation> getAllDonations()
      +
      +
      +
    • +
    • +
      +

      findDonationById

      +
      +
      public Optional<Donation> findDonationById(UUID donationId)
      +
      +
      +
    • +
    • +
      +

      addDonation

      +
      +
      public void addDonation(Donation donation)
      +
      +
      +
    • +
    • +
      +

      removeDonation

      +
      +
      public boolean removeDonation(UUID donationId)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/UserRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/UserRegistry.html new file mode 100644 index 00000000..1591287f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/UserRegistry.html @@ -0,0 +1,206 @@ + + + + +UserRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class UserRegistry

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.registry.UserRegistry
+
+
+
+
+
public class UserRegistry +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      UserRegistry

      +
      +
      public UserRegistry()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getAllUsers

      +
      +
      public List<User> getAllUsers()
      +
      +
      +
    • +
    • +
      +

      findUserById

      +
      +
      public Optional<User> findUserById(UUID userUUID)
      +
      +
      +
    • +
    • +
      +

      addUser

      +
      +
      public void addUser(User user)
      +
      +
      +
    • +
    • +
      +

      removeUserByUUID

      +
      +
      public boolean removeUserByUUID(UUID userUUID)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/CharityRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/CharityRegistry.html new file mode 100644 index 00000000..58c9fb89 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/CharityRegistry.html @@ -0,0 +1,131 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.registry.CharityRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.registry.CharityRegistry

+
+
Packages that use CharityRegistry
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/DonationRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/DonationRegistry.html new file mode 100644 index 00000000..8ac69329 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/DonationRegistry.html @@ -0,0 +1,92 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.registry.DonationRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.registry.DonationRegistry

+
+
Packages that use DonationRegistry
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/UserRegistry.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/UserRegistry.html new file mode 100644 index 00000000..161eade9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/class-use/UserRegistry.html @@ -0,0 +1,93 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.registry.UserRegistry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.registry.UserRegistry

+
+
Packages that use UserRegistry
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-summary.html new file mode 100644 index 00000000..8280dbb6 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-summary.html @@ -0,0 +1,108 @@ + + + + +ntnu.systemutvikling.team6.models.registry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.models.registry

+
+
+
+
package ntnu.systemutvikling.team6.models.registry
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-tree.html new file mode 100644 index 00000000..5bf47283 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-tree.html @@ -0,0 +1,80 @@ + + + + +ntnu.systemutvikling.team6.models.registry Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.models.registry

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-use.html new file mode 100644 index 00000000..79c75f8a --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/registry/package-use.html @@ -0,0 +1,116 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.models.registry (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.models.registry

+
+ + +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Inbox.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Inbox.html new file mode 100644 index 00000000..3f300ee9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Inbox.html @@ -0,0 +1,253 @@ + + + + +Inbox (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Inbox

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.user.Inbox
+
+
+
+
+
public class Inbox +extends Object
+
Represents a user's inbox that contains messages. Provides methods to add, remove and get +messages.
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Inbox

      +
      +
      public Inbox()
      +
      Creates an empty inbox with no messages.
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getMessages

      +
      +
      public List<Message> getMessages()
      +
      Returns an unmodifiable view of the messages in this inbox.
      +
      +
      Returns:
      +
      an unmodifiable list of messages
      +
      +
      +
      +
    • +
    • +
      +

      findMessageById

      +
      +
      public Optional<Message> findMessageById(UUID messageId)
      +
      Finds a specific message by id.
      +
      +
      Parameters:
      +
      messageId - the id of the message to search for
      +
      Returns:
      +
      messageId the id of the message to remove
      +
      Throws:
      +
      IllegalArgumentException - if messageId is null
      +
      +
      +
      +
    • +
    • +
      +

      addMessage

      +
      +
      public void addMessage(Message message)
      +
      Add´s message to the messages list.
      +
      +
      Parameters:
      +
      message - to be added
      +
      Throws:
      +
      IllegalArgumentException - if message is null
      +
      +
      +
      +
    • +
    • +
      +

      removeMessage

      +
      +
      public boolean removeMessage(UUID messageId)
      +
      Removes a message from the inbox list.
      +
      +
      Parameters:
      +
      messageId - the id to the message to be removed
      +
      Returns:
      +
      true if the message was removed, false if not found
      +
      Throws:
      +
      IllegalArgumentException - if messageId is null
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Language.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Language.html new file mode 100644 index 00000000..feef2b9f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Language.html @@ -0,0 +1,241 @@ + + + + +Language (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Enum Class Language

+
+
java.lang.Object +
java.lang.Enum<Language> +
ntnu.systemutvikling.team6.models.user.Language
+
+
+
+
+
All Implemented Interfaces:
+
Serializable, Comparable<Language>, Constable
+
+
+
+
public enum Language +extends Enum<Language>
+
Supported application languages.
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Enum Constant Details

    +
      +
    • +
      +

      NORWEGIAN

      +
      +
      public static final Language NORWEGIAN
      +
      +
      +
    • +
    • +
      +

      ENGLISH

      +
      +
      public static final Language ENGLISH
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      values

      +
      +
      public static Language[] values()
      +
      Returns an array containing the constants of this enum class, in +the order they are declared.
      +
      +
      Returns:
      +
      an array containing the constants of this enum class, in the order they are declared
      +
      +
      +
      +
    • +
    • +
      +

      valueOf

      +
      +
      public static Language valueOf(String name)
      +
      Returns the enum constant of this class with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this class. (Extraneous whitespace characters are +not permitted.)
      +
      +
      Parameters:
      +
      name - the name of the enum constant to be returned.
      +
      Returns:
      +
      the enum constant with the specified name
      +
      Throws:
      +
      IllegalArgumentException - if this enum class has no constant with the specified name
      +
      NullPointerException - if the argument is null
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Message.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Message.html new file mode 100644 index 00000000..62db5588 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Message.html @@ -0,0 +1,269 @@ + + + + +Message (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Message

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.user.Message
+
+
+
+
+
public class Message +extends Object
+
Represents a message.
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Message

      +
      +
      public Message(String title, + UUID from, + String content)
      +
      Creates a message with a unique identifier. The message includes a title, a string who it's +from, content and the time and date.
      +
      +
      Parameters:
      +
      title - the title of the message
      +
      from - who the message is from
      +
      content - the content of the message
      +
      Throws:
      +
      IllegalArgumentException - if title, from or content is null or blank.
      +
      +
      +
      +
    • +
    • +
      +

      Message

      +
      +
      public Message(String title, + UUID from, + String content, + LocalDate date)
      +
      Creates a message with a unique identifier. The message includes a title, a string who it's +from, content and the time and date. This one creates a message that has been created before.
      +
      +
      Parameters:
      +
      title - the title of the message
      +
      from - who the message is from
      +
      content - the content of the message
      +
      date - date of when the message was created
      +
      Throws:
      +
      IllegalArgumentException - if title, from or content is null or blank.
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getId

      +
      +
      public UUID getId()
      +
      +
      +
    • +
    • +
      +

      getTitle

      +
      +
      public String getTitle()
      +
      +
      +
    • +
    • +
      +

      getFrom

      +
      +
      public UUID getFrom()
      +
      +
      +
    • +
    • +
      +

      getContent

      +
      +
      public String getContent()
      +
      +
      +
    • +
    • +
      +

      getTimeAndDate

      +
      +
      public LocalDate getTimeAndDate()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Role.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Role.html new file mode 100644 index 00000000..0a88f513 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Role.html @@ -0,0 +1,241 @@ + + + + +Role (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Enum Class Role

+
+
java.lang.Object +
java.lang.Enum<Role> +
ntnu.systemutvikling.team6.models.user.Role
+
+
+
+
+
All Implemented Interfaces:
+
Serializable, Comparable<Role>, Constable
+
+
+
+
public enum Role +extends Enum<Role>
+
Available users
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Enum Constant Details

    +
      +
    • +
      +

      NORMAL_USER

      +
      +
      public static final Role NORMAL_USER
      +
      +
      +
    • +
    • +
      +

      CHARITY_USER

      +
      +
      public static final Role CHARITY_USER
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      values

      +
      +
      public static Role[] values()
      +
      Returns an array containing the constants of this enum class, in +the order they are declared.
      +
      +
      Returns:
      +
      an array containing the constants of this enum class, in the order they are declared
      +
      +
      +
      +
    • +
    • +
      +

      valueOf

      +
      +
      public static Role valueOf(String name)
      +
      Returns the enum constant of this class with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this class. (Extraneous whitespace characters are +not permitted.)
      +
      +
      Parameters:
      +
      name - the name of the enum constant to be returned.
      +
      Returns:
      +
      the enum constant with the specified name
      +
      Throws:
      +
      IllegalArgumentException - if this enum class has no constant with the specified name
      +
      NullPointerException - if the argument is null
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Settings.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Settings.html new file mode 100644 index 00000000..1d573d69 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/Settings.html @@ -0,0 +1,275 @@ + + + + +Settings (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class Settings

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.user.Settings
+
+
+
+
+
public class Settings +extends Object
+
Represents the settings for a user.
+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      Settings

      +
      +
      public Settings()
      +
      Sets standard settings. LightMode enabled, language set to English, Anonymous disabled
      +
      +
      +
    • +
    • +
      +

      Settings

      +
      +
      public Settings(boolean anonymous, + Language language, + boolean lightMode)
      +
      Creates settings for a user.
      +
      +
      Parameters:
      +
      anonymous - choose if user is anonymous
      +
      language - choose language
      +
      lightMode - choose between light or dark mode
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      toggleLightMode

      +
      +
      public void toggleLightMode()
      +
      Toggles between light and dark mode
      +
      +
      +
    • +
    • +
      +

      toggleAnonymousMode

      +
      +
      public void toggleAnonymousMode()
      +
      Toggles anonymous mode on and off
      +
      +
      +
    • +
    • +
      +

      changeLanguage

      +
      +
      public void changeLanguage(Language newLanguage)
      +
      Change language to the chosen language.
      +
      +
      Parameters:
      +
      newLanguage - the language to change to.
      +
      +
      +
      +
    • +
    • +
      +

      isLightMode

      +
      +
      public boolean isLightMode()
      +
      +
      +
    • +
    • +
      +

      getLanguage

      +
      +
      public Language getLanguage()
      +
      +
      +
    • +
    • +
      +

      isAnonymous

      +
      +
      public boolean isAnonymous()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/User.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/User.html new file mode 100644 index 00000000..783124d8 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/User.html @@ -0,0 +1,435 @@ + + + + +User (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class User

+
+
java.lang.Object +
ntnu.systemutvikling.team6.models.user.User
+
+
+
+
+
public class User +extends Object
+
Represents a user in the system. + +

A user has a unique identifier, personal information, a hashed password, a role, settings and +an inbox. + +

The password is never stored ad plain text. It is hashed using PasswordHasher

+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      User

      +
      +
      public User(String displayName, + String username, + String email, + String password, + Role role, + Settings settings, + Inbox inbox)
      +
      Creates a new user.
      +
      +
      Parameters:
      +
      displayName - the name of the user that is shown
      +
      username - unqiue username used for login
      +
      email - the email of the user
      +
      password - the password for the user
      +
      role - users role
      +
      settings - the user´s settings
      +
      inbox - the user´s inbox
      +
      Throws:
      +
      IllegalArgumentException - if any required argument is invalid.
      +
      +
      +
      +
    • +
    • +
      +

      User

      +
      +
      public User(String uuid, + String displayName, + String username, + String email, + String password, + String role)
      +
      Creates a new user taylored for getting info from DATABASE. Settings and inbox can be set on a +later date throught another method in databaseManager class
      +
      +
      Parameters:
      +
      uuid - gives the user a unique identifier with UUID
      +
      displayName - the name of the user that is shown
      +
      username - the name of the user
      +
      email - the email of the user
      +
      password - the password for the user
      +
      role - users role
      +
      Throws:
      +
      IllegalArgumentException - if any required argument is invalid.
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getId

      +
      +
      public UUID getId()
      +
      +
      +
    • +
    • +
      +

      getDisplayName

      +
      +
      public String getDisplayName()
      +
      +
      +
    • +
    • +
      +

      getUsername

      +
      +
      public String getUsername()
      +
      +
      +
    • +
    • +
      +

      getEmail

      +
      +
      public String getEmail()
      +
      +
      +
    • +
    • +
      +

      getPasswordHash

      +
      +
      public String getPasswordHash()
      +
      +
      +
    • +
    • +
      +

      getRole

      +
      +
      public Role getRole()
      +
      +
      +
    • +
    • +
      +

      getSettings

      +
      +
      public Settings getSettings()
      +
      +
      +
    • +
    • +
      +

      getInbox

      +
      +
      public Inbox getInbox()
      +
      +
      +
    • +
    • +
      +

      setUsername

      +
      +
      public void setUsername(String name)
      +
      Updates the users name.
      +
      +
      Parameters:
      +
      name - the new name
      +
      Throws:
      +
      IllegalArgumentException - if the name is null or blank
      +
      +
      +
      +
    • +
    • +
      +

      setPassword

      +
      +
      public void setPassword(String password)
      +
      Updates the users password. + +

      The password is hashed before being stored.

      +
      +
      Parameters:
      +
      password - the new password
      +
      +
      +
      +
    • +
    • +
      +

      setEmail

      +
      +
      public void setEmail(String email)
      +
      Updates the users email.
      +
      +
      Parameters:
      +
      email - the new email
      +
      Throws:
      +
      IllegalArgumentException - if the email is null, blank, or does not contain '@' or '.'
      +
      +
      +
      +
    • +
    • +
      +

      checkPassword

      +
      +
      public boolean checkPassword(String password)
      +
      Checks if the provided password matches the stored password.
      +
      +
      Parameters:
      +
      password - the password to verify
      +
      Returns:
      +
      true if the password is correct, false otherwise
      +
      +
      +
      +
    • +
    • +
      +

      setSettings

      +
      +
      public void setSettings(Settings settings)
      +
      +
      +
    • +
    • +
      +

      setInbox

      +
      +
      public void setInbox(Inbox inbox)
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Inbox.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Inbox.html new file mode 100644 index 00000000..4ad1d3d7 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Inbox.html @@ -0,0 +1,135 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.user.Inbox (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.user.Inbox

+
+
Packages that use Inbox
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Language.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Language.html new file mode 100644 index 00000000..1881b381 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Language.html @@ -0,0 +1,136 @@ + + + + +Uses of Enum Class ntnu.systemutvikling.team6.models.user.Language (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Enum Class
ntnu.systemutvikling.team6.models.user.Language

+
+
Packages that use Language
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Message.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Message.html new file mode 100644 index 00000000..d7646a44 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Message.html @@ -0,0 +1,108 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.user.Message (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.user.Message

+
+
Packages that use Message
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Role.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Role.html new file mode 100644 index 00000000..73c4c08b --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Role.html @@ -0,0 +1,129 @@ + + + + +Uses of Enum Class ntnu.systemutvikling.team6.models.user.Role (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Enum Class
ntnu.systemutvikling.team6.models.user.Role

+
+
Packages that use Role
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Settings.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Settings.html new file mode 100644 index 00000000..1d61de84 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/Settings.html @@ -0,0 +1,134 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.user.Settings (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.user.Settings

+
+
Packages that use Settings
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/User.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/User.html new file mode 100644 index 00000000..923ad4d0 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/class-use/User.html @@ -0,0 +1,247 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.models.user.User (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.models.user.User

+
+
Packages that use User
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-summary.html new file mode 100644 index 00000000..de162fe8 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-summary.html @@ -0,0 +1,128 @@ + + + + +ntnu.systemutvikling.team6.models.user (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.models.user

+
+
+
+
package ntnu.systemutvikling.team6.models.user
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-tree.html new file mode 100644 index 00000000..8a6c8e53 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-tree.html @@ -0,0 +1,96 @@ + + + + +ntnu.systemutvikling.team6.models.user Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.models.user

+
+Package Hierarchies: + +
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • ntnu.systemutvikling.team6.models.user.Inbox
    • +
    • ntnu.systemutvikling.team6.models.user.Message
    • +
    • ntnu.systemutvikling.team6.models.user.Settings
    • +
    • ntnu.systemutvikling.team6.models.user.User
    • +
    +
  • +
+
+
+

Enum Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-use.html new file mode 100644 index 00000000..a0e57025 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/models/user/package-use.html @@ -0,0 +1,202 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.models.user (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.models.user

+
+ + +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-summary.html new file mode 100644 index 00000000..66c7f381 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-summary.html @@ -0,0 +1,114 @@ + + + + +ntnu.systemutvikling.team6 (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6

+
+
+
+
package ntnu.systemutvikling.team6
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-tree.html new file mode 100644 index 00000000..5c3585d0 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-tree.html @@ -0,0 +1,83 @@ + + + + +ntnu.systemutvikling.team6 Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6

+
+Package Hierarchies: + +
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • javafx.application.Application + +
    • +
    • ntnu.systemutvikling.team6.Main
    • +
    +
  • +
+
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-use.html new file mode 100644 index 00000000..ea949481 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/package-use.html @@ -0,0 +1,65 @@ + + + + +Uses of Package ntnu.systemutvikling.team6 (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6

+
+No usage of ntnu.systemutvikling.team6 + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/FullCharityScrape.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/FullCharityScrape.html new file mode 100644 index 00000000..9d609247 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/FullCharityScrape.html @@ -0,0 +1,229 @@ + + + + +FullCharityScrape (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class FullCharityScrape

+
+
java.lang.Object +
ntnu.systemutvikling.team6.scraper.FullCharityScrape
+
+
+
+
+
public class FullCharityScrape +extends Object
+
Orchestrates a full charity data scrape by combining two data sources: + +
    +
  1. The external charity API (via APICharityScraper), which provides structured data + such as organisation numbers, approval status, and charity URLs. +
  2. Individual charity web pages (via URLCharityScraper), which provide richer + presentation data such as descriptions, logos, categories, and key values. +
+ +

This class acts as a facade — callers only need to invoke getAPIAndURLCharityData() +to receive a fully populated CharityRegistry.

+
+
+
+ +
+
+ +
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/LogoDownloader.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/LogoDownloader.html new file mode 100644 index 00000000..f5c1a4f9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/LogoDownloader.html @@ -0,0 +1,203 @@ + + + + +LogoDownloader (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class LogoDownloader

+
+
java.lang.Object +
ntnu.systemutvikling.team6.scraper.LogoDownloader
+
+
+
+
+
public class LogoDownloader +extends Object
+
Facilitates downloading of .png images from the individual charity's page on IK, converting them +to bytecode (blob), and then back to a .png.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      LogoDownloader

      +
      +
      public LogoDownloader()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      downloadImageAsBlob

      +
      +
      public static byte[] downloadImageAsBlob(String imageUrl)
      +
      Downloads a image from the given URL and converts it to a blob.
      +
      +
      Parameters:
      +
      imageUrl - the URL of the image
      +
      Returns:
      +
      a blob containing the image data
      +
      +
      +
      +
    • +
    • +
      +

      convertBlobToPNG

      +
      +
      public static void convertBlobToPNG(byte[] imageBytes, + String fileName)
      +
      Converts a blob of image data back to a .png image file.
      +
      +
      Parameters:
      +
      imageBytes - the blob containing the image data
      +
      fileName - the filename of the .png image file
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/FullCharityScrape.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/FullCharityScrape.html new file mode 100644 index 00000000..895ac8c6 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/FullCharityScrape.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.scraper.FullCharityScrape (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.scraper.FullCharityScrape

+
+No usage of ntnu.systemutvikling.team6.scraper.FullCharityScrape + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/LogoDownloader.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/LogoDownloader.html new file mode 100644 index 00000000..ebd31c49 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/class-use/LogoDownloader.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.scraper.LogoDownloader (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.scraper.LogoDownloader

+
+No usage of ntnu.systemutvikling.team6.scraper.LogoDownloader + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-summary.html new file mode 100644 index 00000000..b25e61f1 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-summary.html @@ -0,0 +1,125 @@ + + + + +ntnu.systemutvikling.team6.scraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.scraper

+
+
+
+
package ntnu.systemutvikling.team6.scraper
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-tree.html new file mode 100644 index 00000000..976dd540 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-tree.html @@ -0,0 +1,79 @@ + + + + +ntnu.systemutvikling.team6.scraper Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.scraper

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-use.html new file mode 100644 index 00000000..9c6f7c5a --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/package-use.html @@ -0,0 +1,65 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.scraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.scraper

+
+No usage of ntnu.systemutvikling.team6.scraper + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.html new file mode 100644 index 00000000..238cab2a --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.html @@ -0,0 +1,281 @@ + + + + +APICharityData (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class APICharityData

+
+
java.lang.Object +
ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData
+
+
+
+
+
public class APICharityData +extends Object
+
Represents data parsed from the IK API JSON response. Instances are immutable; to update any +value, a new object must be created. + +

Receives data directly from APICharityScraper. + +

org_number should be a unique number, as it is used as a primary key in DatabaseSetup.

+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      APICharityData

      +
      +
      public APICharityData(String org_number, + String name, + String status, + String url, + boolean is_pre_approved)
      +
      Constructs a new APICharityData object. This class represents the data provided from the IK +Api, and is used expand and provide data to our design of a charity.
      +
      +
      Parameters:
      +
      org_number - a unique number that identifies the organization
      +
      name - the name of the organization
      +
      status - approved for approved organizations, obs for non-approved + organizations
      +
      url - the URL for more info about the organization on the IK domain
      +
      is_pre_approved - whether the organization was pre-approved
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getOrg_number

      +
      +
      public String getOrg_number()
      +
      Returns the organization number. Must not be null or blank.
      +
      +
      Returns:
      +
      the organization number
      +
      +
      +
      +
    • +
    • +
      +

      getName

      +
      +
      public String getName()
      +
      Returns the name of the organization. Whitespace removed.
      +
      +
      Returns:
      +
      the name of the organization
      +
      +
      +
      +
    • +
    • +
      +

      getStatus

      +
      +
      public String getStatus()
      +
      Returns whether the organization is approved or not
      +
      +
      Returns:
      +
      the approved status of the organization
      +
      +
      +
      +
    • +
    • +
      +

      getUrl

      +
      +
      public String getUrl()
      +
      Returns the URL of the organizations information page on IK
      +
      +
      Returns:
      +
      the URL for more info about the organization
      +
      +
      +
      +
    • +
    • +
      +

      getIs_pre_approved

      +
      +
      public boolean getIs_pre_approved()
      +
      Returns whether the organization was pre-approved.
      +
      +
      Returns:
      +
      true if organization was pre-approved
      + false otherwise
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.html new file mode 100644 index 00000000..9c27eb87 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.html @@ -0,0 +1,243 @@ + + + + +APICharityScraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class APICharityScraper

+
+
java.lang.Object +
ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper
+
+
+
+
+
public class APICharityScraper +extends Object
+
Fetches JSON information from the IK API and parses the JSON into a list of APICharityData objects. AND can update the database.
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      APICharityScraper

      +
      +
      public APICharityScraper(HttpClient client) + throws URISyntaxException
      +
      Constructs a new APICharityScraper object.
      +
      +
      Parameters:
      +
      client - the client responsible for making the http connection.
      +
      Throws:
      +
      URISyntaxException - if the API URL is malformed or violates URI syntax rules
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      checkConnection

      +
      +
      public boolean checkConnection() + throws IOException, +InterruptedException
      +
      Checks if the http request returns an 'OK' response.
      +
      +
      Returns:
      +
      true if connection was successful
      +
      Throws:
      +
      IOException - if an I/O error occurs while sending or receiving the HTTP reques
      +
      InterruptedException - if the operation is interrupted while waiting for the response
      +
      RuntimeException - if the connection is unsuccessful
      +
      +
      +
      +
    • +
    • +
      +

      getJSONData

      +
      +
      public String getJSONData() + throws IOException, +InterruptedException
      +
      Fetches the JSON data from the IK API and stores it in a String.
      +
      +
      Returns:
      +
      a String of the JSON values in IK API
      +
      Throws:
      +
      IOException - if an I/O error occurs while sending or receiving the HTTP request
      +
      InterruptedException - if the operation is interrupted while waiting for the response
      +
      +
      +
      +
    • +
    • +
      +

      parseJSON

      +
      +
      public CharityRegistry parseJSON(String JSONData)
      +
      Parses the JSON data using gson and translates the APICharityData into our predefined +charity classes and puts it in a CharityRegistry object.
      +
      +
      Parameters:
      +
      JSONData - the String of JSON data to be parsed
      +
      Returns:
      +
      a CharityRegistry class object
      +
      Throws:
      +
      com.google.gson.JsonSyntaxException - if the provided JSON is not valid
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.html new file mode 100644 index 00000000..c96e5b84 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.html @@ -0,0 +1,385 @@ + + + + +URLCharityScraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class URLCharityScraper

+
+
java.lang.Object +
ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper
+
+
+
+
+
public class URLCharityScraper +extends Object
+
Class for scraping the description, URL of the logo, string of categories, and key values of the +charities registered in IK.
+
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    + +
    +
    Constructor used for production code.
    +
    +
    URLCharityScraper(String url, + org.openqa.selenium.WebDriver driver)
    +
    +
    Constructor used for testing.
    +
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    protected void
    + +
    +
    Quits the driver instance, making it unusable.
    +
    +
    protected org.openqa.selenium.support.ui.WebDriverWait
    + +
    +
    Creates a WebDriverWait object for halting scraping until the correct pre-conditions +are met.
    +
    +
    protected org.openqa.selenium.WebElement
    +
    findElement(org.openqa.selenium.By by)
    +
    +
    Calls the findElement method from the WebDriver object and returns a list of +the returned WebElement objects.
    +
    +
    List<org.openqa.selenium.WebElement>
    +
    findElements(org.openqa.selenium.By by)
    +
    +
    Calls the findElements method from the WebDriver object and returns a list of +the returned WebElement objects.
    +
    + + +
    +
    Returns a String of the categories for the charity with ',' as a delimiter.
    +
    + + +
    +
    Returns the description of the charity.
    +
    + + +
    +
    Returns a String of the key value percentages for the charity with ':' as a delimiter, verified +by IK.
    +
    + + +
    +
    Returns the URL of the logo for the charity.
    +
    +
    void
    + +
    +
    Runs all the scraper methods at once, updating the object parameters.
    +
    +
    protected void
    + +
    +
    Scrapes the URL for the paragraphs containing the description of the charity.
    +
    +
    +
    +
    +
    +

    Methods inherited from class Object

    +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      URLCharityScraper

      +
      +
      public URLCharityScraper(String url)
      +
      Constructor used for production code. + +

      It initializes the lists used for categories and keyValues, as well as defining the +parameters used for the selenium Chromium-based browser that does the scraping.

      +
      +
      Parameters:
      +
      url - the URL for the charity's webpage on IK
      +
      +
      +
      +
    • +
    • +
      +

      URLCharityScraper

      +
      +
      public URLCharityScraper(String url, + org.openqa.selenium.WebDriver driver)
      +
      Constructor used for testing. + +

      It accepts both a url (should ideally be a dud) and a WebDriver as parameters. The +WebDriver is passed to make testing easier.

      +
      +
      Parameters:
      +
      url - the URL for the charity's webpage on IK (for this constructor it should not be a + real URL)
      +
      driver - the WebDriver object used for scraping
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      createWait

      +
      +
      protected org.openqa.selenium.support.ui.WebDriverWait createWait()
      +
      Creates a WebDriverWait object for halting scraping until the correct pre-conditions +are met.
      +
      +
      Returns:
      +
      the WebDriverWait object to be used in the methods
      +
      +
      +
      +
    • +
    • +
      +

      findElements

      +
      +
      public List<org.openqa.selenium.WebElement> findElements(org.openqa.selenium.By by)
      +
      Calls the findElements method from the WebDriver object and returns a list of +the returned WebElement objects.
      +
      +
      Parameters:
      +
      by - a selector for WebElement objects
      +
      Returns:
      +
      a list of found WebElement objects matching the given selector
      +
      +
      +
      +
    • +
    • +
      +

      findElement

      +
      +
      protected org.openqa.selenium.WebElement findElement(org.openqa.selenium.By by)
      +
      Calls the findElement method from the WebDriver object and returns a list of +the returned WebElement objects.
      +
      +
      Parameters:
      +
      by - a selector for WebElement objects
      +
      Returns:
      +
      a list of found WebElement objects matching the given selector
      +
      +
      +
      +
    • +
    • +
      +

      closeDriver

      +
      +
      protected void closeDriver()
      +
      Quits the driver instance, making it unusable.
      +
      +
      +
    • +
    • +
      +

      updateDescription

      +
      +
      protected void updateDescription()
      +
      Scrapes the URL for the paragraphs containing the description of the charity.
      +
      +
      +
    • +
    • +
      +

      scrapeCharityPage

      +
      +
      public void scrapeCharityPage()
      +
      Runs all the scraper methods at once, updating the object parameters.
      +
      +
      +
    • +
    • +
      +

      getDescription

      +
      +
      public String getDescription()
      +
      Returns the description of the charity.
      +
      +
      Returns:
      +
      a String containing the description of the charity.
      +
      +
      +
      +
    • +
    • +
      +

      getLogoURL

      +
      +
      public String getLogoURL()
      +
      Returns the URL of the logo for the charity.
      +
      +
      Returns:
      +
      a String containing the URL for the logo of the charity.
      +
      +
      +
      +
    • +
    • +
      +

      getCategories

      +
      +
      public List<String> getCategories()
      +
      Returns a String of the categories for the charity with ',' as a delimiter.
      +
      +
      Returns:
      +
      a String of strings containing the categories for the charity
      +
      +
      +
      +
    • +
    • +
      +

      getKeyValues

      +
      +
      public String getKeyValues()
      +
      Returns a String of the key value percentages for the charity with ':' as a delimiter, verified +by IK.
      +
      +
      Returns:
      +
      a String of the key values for the charity-
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityData.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityData.html new file mode 100644 index 00000000..e79ebe42 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityData.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData

+
+No usage of ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityData + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityScraper.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityScraper.html new file mode 100644 index 00000000..8370f582 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/APICharityScraper.html @@ -0,0 +1,90 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper

+
+
Packages that use APICharityScraper
+
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/URLCharityScraper.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/URLCharityScraper.html new file mode 100644 index 00000000..6b6198be --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/class-use/URLCharityScraper.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper

+
+No usage of ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-summary.html new file mode 100644 index 00000000..af48c4fd --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-summary.html @@ -0,0 +1,113 @@ + + + + +ntnu.systemutvikling.team6.scraper.scraperComponents (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.scraper.scraperComponents

+
+
+
+
package ntnu.systemutvikling.team6.scraper.scraperComponents
+
+
+
    +
  • + +
  • +
  • +
    +
    Classes
    +
    +
    Class
    +
    Description
    + +
    +
    Represents data parsed from the IK API JSON response.
    +
    + +
    +
    Fetches JSON information from the IK API and parses the JSON into a list of APICharityData objects.
    +
    + +
    +
    Class for scraping the description, URL of the logo, string of categories, and key values of the +charities registered in IK.
    +
    +
    +
    +
  • +
+
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-tree.html new file mode 100644 index 00000000..ac0577e7 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-tree.html @@ -0,0 +1,80 @@ + + + + +ntnu.systemutvikling.team6.scraper.scraperComponents Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.scraper.scraperComponents

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-use.html new file mode 100644 index 00000000..0741b8a9 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/scraper/scraperComponents/package-use.html @@ -0,0 +1,88 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.scraper.scraperComponents (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.scraper.scraperComponents

+
+ +
+
Package
+
Description
+ +
 
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/PasswordHasher.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/PasswordHasher.html new file mode 100644 index 00000000..2e448ae7 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/PasswordHasher.html @@ -0,0 +1,213 @@ + + + + +PasswordHasher (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class PasswordHasher

+
+
java.lang.Object +
ntnu.systemutvikling.team6.security.PasswordHasher
+
+
+
+
+
public final class PasswordHasher +extends Object
+
A utility for hashing and verifying passwords using PBKDF2. + +

The generated hash contains both a random salt and the hashed password, encoded as Base64 +string.

+
+
Author:
+
Robin Strand Prestmo
+
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      PasswordHasher

      +
      +
      public PasswordHasher()
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getHashPassword

      +
      +
      public String getHashPassword(String password)
      +
      Hashes a password using PBKDF2 and a random salt.
      +
      +
      Parameters:
      +
      password - the password to hash.
      +
      Returns:
      +
      a Base64 string containing the salt and the hashed password.
      +
      Throws:
      +
      IllegalArgumentException - if the password is null or blank.
      +
      +
      +
      +
    • +
    • +
      +

      isValidPassword

      +
      +
      public boolean isValidPassword(String password, + String hashPass)
      +
      Checks if the password matches a perviously stored hash.
      +
      +
      Parameters:
      +
      password - The password the user types.
      +
      hashPass - Is the stored hashed password
      +
      Returns:
      +
      True if password is valid, otherwise false.
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/class-use/PasswordHasher.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/class-use/PasswordHasher.html new file mode 100644 index 00000000..f721f42e --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/class-use/PasswordHasher.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.security.PasswordHasher (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.security.PasswordHasher

+
+No usage of ntnu.systemutvikling.team6.security.PasswordHasher + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-summary.html new file mode 100644 index 00000000..4769560f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-summary.html @@ -0,0 +1,114 @@ + + + + +ntnu.systemutvikling.team6.security (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.security

+
+
+
+
package ntnu.systemutvikling.team6.security
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-tree.html new file mode 100644 index 00000000..672ccade --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-tree.html @@ -0,0 +1,78 @@ + + + + +ntnu.systemutvikling.team6.security Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.security

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-use.html new file mode 100644 index 00000000..747211f3 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/security/package-use.html @@ -0,0 +1,65 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.security (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.security

+
+No usage of ntnu.systemutvikling.team6.security + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/APIToDatabaseService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/APIToDatabaseService.html new file mode 100644 index 00000000..20d8d066 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/APIToDatabaseService.html @@ -0,0 +1,194 @@ + + + + +APIToDatabaseService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class APIToDatabaseService

+
+
java.lang.Object +
ntnu.systemutvikling.team6.service.APIToDatabaseService
+
+
+
+
+
public class APIToDatabaseService +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      APIToDatabaseService

      +
      +
      public APIToDatabaseService(DatabaseConnection connection)
      +
      Contractor for APIToDatabaseService. It uses a DatabaseConnection object that contains a +connection credentials.
      +
      +
      Parameters:
      +
      connection -
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      addAPIDataToTable

      +
      +
      public void addAPIDataToTable(List<Charity> charities)
      +
      This method is used to verify the integrity of the data in the charities table and to +update it based on the data retrieved from the IK API and the charity's URL. The param +charities are retrieved from the IK API through the APICharityData class. Called in initialize +method in HmHApplication.java, which is the main class of the application, to ensure that the +data is up to date when the application starts. Uses a temp table to ensure that the data in +the database is consistent with the data from the API. + +

      Uses a URLScraper object to get data not contained in the API, and static methods from +LogoDownloader to get the charity's logo as a blob.

      +
      +
      Parameters:
      +
      charities - a list of Charity objects to add to the database
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/AuthenticationService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/AuthenticationService.html new file mode 100644 index 00000000..0b797c82 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/AuthenticationService.html @@ -0,0 +1,287 @@ + + + + +AuthenticationService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class AuthenticationService

+
+
java.lang.Object +
ntnu.systemutvikling.team6.service.AuthenticationService
+
+
+
+
+
public class AuthenticationService +extends Object
+
Service class responsible for handling user authentication operations, including login, +registration, and logout functionality. + +

Maintains the state of the currently authenticated user throughout the session.

+
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    +
    AuthenticationService(UserSelect userDataReader, + UserDAO userDataSender)
    +
    +
    Constructs an AuthenticationService with the specified data access objects.
    +
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    + + +
    +
    Returns the currently authenticated user.
    +
    +
    boolean
    + +
    +
    Checks whether a user is currently logged in.
    +
    +
    boolean
    +
    login(String username, + String password)
    +
    +
    Attempts to authenticate a user with the given credentials.
    +
    +
    void
    + +
    +
    Logs out the currently authenticated user by clearing the current user state.
    +
    +
    boolean
    +
    register(String displayName, + String username, + String email, + String password)
    +
    +
    Registers a new user account with the provided details.
    +
    +
    +
    +
    +
    +

    Methods inherited from class Object

    +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      AuthenticationService

      +
      +
      public AuthenticationService(UserSelect userDataReader, + UserDAO userDataSender)
      +
      Constructs an AuthenticationService with the specified data access objects.
      +
      +
      Parameters:
      +
      userDataReader - the data reader used to query user information from the database
      +
      userDataSender - the DAO used to persist new user registrations to the database
      +
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      login

      +
      +
      public boolean login(String username, + String password)
      +
      Attempts to authenticate a user with the given credentials. + +

      If a matching user is found in the database, they are set as the current user and the method +returns true.

      +
      +
      Parameters:
      +
      username - the username of the user attempting to log in
      +
      password - the password of the user attempting to log in
      +
      Returns:
      +
      true if authentication was successful; false otherwise
      +
      +
      +
      +
    • +
    • +
      +

      register

      +
      +
      public boolean register(String displayName, + String username, + String email, + String password)
      +
      Registers a new user account with the provided details. + +

      The new user is assigned the Role.NORMAL_USER role and default Settings and +Inbox. Registration will fail if the username is already taken or if the database +operation is unsuccessful. On success, the new user is set as the current user.

      +
      +
      Parameters:
      +
      displayName - the display name shown on the user's profile
      +
      username - the unique username for the new account
      +
      email - the email address associated with the new account
      +
      password - the password for the new account
      +
      Returns:
      +
      true if registration was successful; false if the username is already + taken or the database operation failed
      +
      +
      +
      +
    • +
    • +
      +

      logout

      +
      +
      public void logout()
      +
      Logs out the currently authenticated user by clearing the current user state.
      +
      +
      +
    • +
    • +
      +

      getCurrentUser

      +
      +
      public User getCurrentUser()
      +
      Returns the currently authenticated user.
      +
      +
      Returns:
      +
      the current User, or null if no user is logged in
      +
      +
      +
      +
    • +
    • +
      +

      isLoggedin

      +
      +
      public boolean isLoggedin()
      +
      Checks whether a user is currently logged in.
      +
      +
      Returns:
      +
      true if a user is authenticated; false otherwise
      +
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/CharityService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/CharityService.html new file mode 100644 index 00000000..b16acc83 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/CharityService.html @@ -0,0 +1,136 @@ + + + + +CharityService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class CharityService

+
+
java.lang.Object +
ntnu.systemutvikling.team6.service.CharityService
+
+
+
+
+
public class CharityService +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CharityService

      +
      +
      public CharityService()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/DonationService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/DonationService.html new file mode 100644 index 00000000..e9f26157 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/DonationService.html @@ -0,0 +1,136 @@ + + + + +DonationService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class DonationService

+
+
java.lang.Object +
ntnu.systemutvikling.team6.service.DonationService
+
+
+
+
+
public class DonationService +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      DonationService

      +
      +
      public DonationService()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/FeedbackService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/FeedbackService.html new file mode 100644 index 00000000..0784bdb5 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/FeedbackService.html @@ -0,0 +1,136 @@ + + + + +FeedbackService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+ +
+

Class FeedbackService

+
+
java.lang.Object +
ntnu.systemutvikling.team6.service.FeedbackService
+
+
+
+
+
public class FeedbackService +extends Object
+
+
+
+ +
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      FeedbackService

      +
      +
      public FeedbackService()
      +
      +
      +
    • +
    +
    +
  • +
+
+ + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/APIToDatabaseService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/APIToDatabaseService.html new file mode 100644 index 00000000..f2042058 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/APIToDatabaseService.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.service.APIToDatabaseService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.service.APIToDatabaseService

+
+No usage of ntnu.systemutvikling.team6.service.APIToDatabaseService + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/AuthenticationService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/AuthenticationService.html new file mode 100644 index 00000000..fb656f1f --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/AuthenticationService.html @@ -0,0 +1,99 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.service.AuthenticationService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.service.AuthenticationService

+
+
Packages that use AuthenticationService
+ +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/CharityService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/CharityService.html new file mode 100644 index 00000000..a75cfdc5 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/CharityService.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.service.CharityService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.service.CharityService

+
+No usage of ntnu.systemutvikling.team6.service.CharityService + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/DonationService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/DonationService.html new file mode 100644 index 00000000..e5cfdea6 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/DonationService.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.service.DonationService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.service.DonationService

+
+No usage of ntnu.systemutvikling.team6.service.DonationService + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/FeedbackService.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/FeedbackService.html new file mode 100644 index 00000000..1cdc9f91 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/class-use/FeedbackService.html @@ -0,0 +1,66 @@ + + + + +Uses of Class ntnu.systemutvikling.team6.service.FeedbackService (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Class
ntnu.systemutvikling.team6.service.FeedbackService

+
+No usage of ntnu.systemutvikling.team6.service.FeedbackService + +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-summary.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-summary.html new file mode 100644 index 00000000..35118732 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-summary.html @@ -0,0 +1,123 @@ + + + + +ntnu.systemutvikling.team6.service (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+ +
+
+

Package ntnu.systemutvikling.team6.service

+
+
+
+
package ntnu.systemutvikling.team6.service
+
+
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-tree.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-tree.html new file mode 100644 index 00000000..e6eb74bc --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-tree.html @@ -0,0 +1,82 @@ + + + + +ntnu.systemutvikling.team6.service Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For Package ntnu.systemutvikling.team6.service

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-use.html b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-use.html new file mode 100644 index 00000000..5de7ab61 --- /dev/null +++ b/docs/Javadoc/apidocs/ntnu/systemutvikling/team6/service/package-use.html @@ -0,0 +1,89 @@ + + + + +Uses of Package ntnu.systemutvikling.team6.service (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Uses of Package
ntnu.systemutvikling.team6.service

+
+ + +
+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/options b/docs/Javadoc/apidocs/options new file mode 100644 index 00000000..568b04cc --- /dev/null +++ b/docs/Javadoc/apidocs/options @@ -0,0 +1,25 @@ +--no-fonts +-classpath +'C:/Users/robin/.m2/repository/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-controls/25.0.1/javafx-controls-25.0.1.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-controls/25.0.1/javafx-controls-25.0.1-win.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-graphics/25.0.1/javafx-graphics-25.0.1.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-graphics/25.0.1/javafx-graphics-25.0.1-win.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-base/25.0.1/javafx-base-25.0.1.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-base/25.0.1/javafx-base-25.0.1-win.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-fxml/21/javafx-fxml-21.jar;C:/Users/robin/.m2/repository/org/openjfx/javafx-fxml/21/javafx-fxml-21-win.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-java/4.43.0/selenium-java-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-api/4.43.0/selenium-api-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-chrome-driver/4.43.0/selenium-chrome-driver-4.43.0.jar;C:/Users/robin/.m2/repository/com/google/auto/service/auto-service-annotations/1.1.1/auto-service-annotations-1.1.1.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-chromium-driver/4.43.0/selenium-chromium-driver-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-json/4.43.0/selenium-json-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-manager/4.43.0/selenium-manager-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-devtools-v145/4.43.0/selenium-devtools-v145-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-devtools-v146/4.43.0/selenium-devtools-v146-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-devtools-v147/4.43.0/selenium-devtools-v147-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-edge-driver/4.43.0/selenium-edge-driver-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-firefox-driver/4.43.0/selenium-firefox-driver-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-http/4.43.0/selenium-http-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-ie-driver/4.43.0/selenium-ie-driver-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-remote-driver/4.43.0/selenium-remote-driver-4.43.0.jar;C:/Users/robin/.m2/repository/com/google/guava/guava/33.5.0-jre/guava-33.5.0-jre.jar;C:/Users/robin/.m2/repository/com/google/guava/failureaccess/1.0.3/failureaccess-1.0.3.jar;C:/Users/robin/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:/Users/robin/.m2/repository/com/google/j2objc/j2objc-annotations/3.1/j2objc-annotations-3.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-api/1.60.1/opentelemetry-api-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-context/1.60.1/opentelemetry-context-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-common/1.60.1/opentelemetry-common-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-exporter-logging/1.60.1/opentelemetry-exporter-logging-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-common/1.60.1/opentelemetry-sdk-common-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi/1.60.1/opentelemetry-sdk-extension-autoconfigure-spi-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-extension-autoconfigure/1.60.1/opentelemetry-sdk-extension-autoconfigure-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-trace/1.60.1/opentelemetry-sdk-trace-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk/1.60.1/opentelemetry-sdk-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-metrics/1.60.1/opentelemetry-sdk-metrics-1.60.1.jar;C:/Users/robin/.m2/repository/io/opentelemetry/opentelemetry-sdk-logs/1.60.1/opentelemetry-sdk-logs-1.60.1.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-os/4.43.0/selenium-os-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-safari-driver/4.43.0/selenium-safari-driver-4.43.0.jar;C:/Users/robin/.m2/repository/org/seleniumhq/selenium/selenium-support/4.43.0/selenium-support-4.43.0.jar;C:/Users/robin/.m2/repository/com/opencsv/opencsv/5.12.0/opencsv-5.12.0.jar;C:/Users/robin/.m2/repository/org/apache/commons/commons-lang3/3.18.0/commons-lang3-3.18.0.jar;C:/Users/robin/.m2/repository/org/apache/commons/commons-text/1.13.1/commons-text-1.13.1.jar;C:/Users/robin/.m2/repository/commons-beanutils/commons-beanutils/1.11.0/commons-beanutils-1.11.0.jar;C:/Users/robin/.m2/repository/commons-logging/commons-logging/1.3.5/commons-logging-1.3.5.jar;C:/Users/robin/.m2/repository/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar;C:/Users/robin/.m2/repository/org/apache/commons/commons-collections4/4.5.0/commons-collections4-4.5.0.jar;C:/Users/robin/.m2/repository/com/google/code/gson/gson/2.13.2/gson-2.13.2.jar;C:/Users/robin/.m2/repository/com/google/errorprone/error_prone_annotations/2.41.0/error_prone_annotations-2.41.0.jar;C:/Users/robin/.m2/repository/net/bytebuddy/byte-buddy/1.17.7/byte-buddy-1.17.7.jar;C:/Users/robin/.m2/repository/com/mysql/mysql-connector-j/9.6.0/mysql-connector-j-9.6.0.jar;C:/Users/robin/.m2/repository/com/google/protobuf/protobuf-java/4.31.1/protobuf-java-4.31.1.jar' +-encoding +'UTF-8' +-protected +-source +'25' +-sourcepath +'C:/Users/robin/Skole Ikke OneDrive/Systemutvikling/Prosjekt-Repo/helpmehelpapplication/src/main/java' +-author +-bottom +'Copyright © 2026. All rights reserved.' +-charset +'UTF-8' +-d +'C:/Users/robin/Skole Ikke OneDrive/Systemutvikling/Prosjekt-Repo/helpmehelpapplication/target/reports/apidocs' +-docencoding +'UTF-8' +-doctitle +'helpmehelpapplication 1.0-SNAPSHOT API' +-use +-version +-windowtitle +'helpmehelpapplication 1.0-SNAPSHOT API' diff --git a/docs/Javadoc/apidocs/overview-summary.html b/docs/Javadoc/apidocs/overview-summary.html new file mode 100644 index 00000000..57ea2b52 --- /dev/null +++ b/docs/Javadoc/apidocs/overview-summary.html @@ -0,0 +1,26 @@ + + + + +helpmehelpapplication 1.0-SNAPSHOT API + + + + + + + + + + + +
+ +

index.html

+
+ + diff --git a/docs/Javadoc/apidocs/overview-tree.html b/docs/Javadoc/apidocs/overview-tree.html new file mode 100644 index 00000000..c5898c0b --- /dev/null +++ b/docs/Javadoc/apidocs/overview-tree.html @@ -0,0 +1,151 @@ + + + + +Class Hierarchy (helpmehelpapplication 1.0-SNAPSHOT API) + + + + + + + + + + + + + + +
+ +
+
+
+
+

Hierarchy For All Packages

+
+Package Hierarchies: + +
+

Class Hierarchy

+ +
+
+

Interface Hierarchy

+ +
+
+

Enum Class Hierarchy

+ +
+ +
+
+ + diff --git a/docs/Javadoc/apidocs/package-search-index.js b/docs/Javadoc/apidocs/package-search-index.js new file mode 100644 index 00000000..9a62d5aa --- /dev/null +++ b/docs/Javadoc/apidocs/package-search-index.js @@ -0,0 +1 @@ +packageSearchIndex = [{"l":"All Packages","u":"allpackages-index.html","k":"18"},{"l":"ntnu.systemutvikling.team6"},{"l":"ntnu.systemutvikling.team6.controller"},{"l":"ntnu.systemutvikling.team6.controller.components"},{"l":"ntnu.systemutvikling.team6.database"},{"l":"ntnu.systemutvikling.team6.database.DAO"},{"l":"ntnu.systemutvikling.team6.database.Readers"},{"l":"ntnu.systemutvikling.team6.models"},{"l":"ntnu.systemutvikling.team6.models.registry"},{"l":"ntnu.systemutvikling.team6.models.user"},{"l":"ntnu.systemutvikling.team6.scraper"},{"l":"ntnu.systemutvikling.team6.scraper.scraperComponents"},{"l":"ntnu.systemutvikling.team6.security"},{"l":"ntnu.systemutvikling.team6.service"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/Javadoc/apidocs/packages b/docs/Javadoc/apidocs/packages new file mode 100644 index 00000000..9c843bcd --- /dev/null +++ b/docs/Javadoc/apidocs/packages @@ -0,0 +1,13 @@ +ntnu.systemutvikling.team6.controller +ntnu.systemutvikling.team6.controller.components +ntnu.systemutvikling.team6.database.DAO +ntnu.systemutvikling.team6.database +ntnu.systemutvikling.team6.database.Readers +ntnu.systemutvikling.team6 +ntnu.systemutvikling.team6.models +ntnu.systemutvikling.team6.models.registry +ntnu.systemutvikling.team6.models.user +ntnu.systemutvikling.team6.scraper +ntnu.systemutvikling.team6.scraper.scraperComponents +ntnu.systemutvikling.team6.security +ntnu.systemutvikling.team6.service \ No newline at end of file diff --git a/docs/Javadoc/apidocs/resource-files/copy.svg b/docs/Javadoc/apidocs/resource-files/copy.svg new file mode 100644 index 00000000..b07ac7e8 --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/copy.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/docs/Javadoc/apidocs/resource-files/glass.svg b/docs/Javadoc/apidocs/resource-files/glass.svg new file mode 100644 index 00000000..ff7df85e --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/glass.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/docs/Javadoc/apidocs/resource-files/jquery-ui.min.css b/docs/Javadoc/apidocs/resource-files/jquery-ui.min.css new file mode 100644 index 00000000..7e0692dc --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/jquery-ui.min.css @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.14.1 - 2025-01-13 +* https://jqueryui.com +* Includes: core.css, autocomplete.css, menu.css +* Copyright OpenJS Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0} \ No newline at end of file diff --git a/docs/Javadoc/apidocs/resource-files/left.svg b/docs/Javadoc/apidocs/resource-files/left.svg new file mode 100644 index 00000000..11a93ff0 --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/left.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/docs/Javadoc/apidocs/resource-files/link.svg b/docs/Javadoc/apidocs/resource-files/link.svg new file mode 100644 index 00000000..58d38ac9 --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/link.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/docs/Javadoc/apidocs/resource-files/right.svg b/docs/Javadoc/apidocs/resource-files/right.svg new file mode 100644 index 00000000..4b54939c --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/right.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/docs/Javadoc/apidocs/resource-files/stylesheet.css b/docs/Javadoc/apidocs/resource-files/stylesheet.css new file mode 100644 index 00000000..f7994c7f --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/stylesheet.css @@ -0,0 +1,1667 @@ +/* + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + */ + +/* + * Javadoc style sheet + */ + +@import url('fonts/dejavu.css'); + +/* + * These CSS custom properties (variables) define the core color and font + * properties used in this stylesheet. + */ +:root { + /* body, block and code fonts */ + --body-font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + --block-font-family: 'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + --code-font-family: 'DejaVu Sans Mono', monospace; + /* Base font sizes for body and code elements */ + --body-font-size: 14.2px; + --block-font-size: 14.4px; + --code-font-size: 14px; + --nav-font-size: 13.4px; + /* Line height for continuous text blocks */ + --block-line-height: 1.5; + --code-line-height: 1.6; + /* Text colors for body and block elements */ + --body-text-color: #181818; + --block-text-color: #181818; + /* Background colors for various elements */ + --body-background-color: #ffffff; + --section-background-color: var(--body-background-color); + --detail-background-color: #ffffff; + --code-background-color: #f5f5f5; + --mark-background-color: #f7f7f7; + --detail-block-color: #f4f4f4; + /* Colors for navigation bar and table captions */ + --navbar-background-color: #4D7A97; + --navbar-text-color: #ffffff; + /* Background color for subnavigation and various headers */ + --subnav-background-color: #dee3e9; + --subnav-link-color: #47688a; + --member-heading-background-color: var(--subnav-background-color); + /* Background and text colors for selected tabs and navigation items */ + --selected-background-color: #f8981d; + --selected-text-color: #253441; + --selected-link-color: #4a698a; + /* Background colors for generated tables */ + --table-header-color: #ebeff4; + --even-row-color: #ffffff; + --odd-row-color: #f0f0f2; + /* Text color for page title */ + --title-color: #2c4557; + /* Text colors for links */ + --link-color: #437291; + --link-color-active: #bb7a2a; + /* Table of contents */ + --toc-background-color: #f8f8f8; + --toc-highlight-color: var(--subnav-background-color); + --toc-hover-color: #e9ecf0; + /* Snippet and pre colors */ + --snippet-background-color: #f2f2f4; + --snippet-text-color: var(--block-text-color); + --snippet-highlight-color: #f7c590; + --pre-background-color: var(--snippet-background-color); + --pre-text-color: var(--snippet-text-color); + /* Border colors for structural elements and user defined tables */ + --border-color: #e6e6e6; + --table-border-color: #000000; + /* Styles for table tabs */ + --tab-border-radius: 2px 2px 0 0; + /* Search input colors */ + --search-input-background-color: #ffffff; + --search-input-text-color: #000000; + --search-input-placeholder-color: #909090; + /* Highlight color for active search tag target */ + --search-tag-highlight-color: #ffff66; + /* Copy button colors and filters */ + --button-border-color: #b0b8c8; + --button-active-filter: brightness(96%); + --button-focus-filter: brightness(104%); + /* Colors for invalid tag notifications */ + --invalid-tag-background-color: #ffe6e6; + --invalid-tag-text-color: #000000; + /* Navigation bar dimensions */ + --top-nav-height: 44px; + --sub-nav-height: 36px; + --nav-height: calc(var(--top-nav-height) + var(--sub-nav-height)); + --max-content-width: 1500px; + --content-margin: 0 auto; +} +/* + * Styles for individual HTML elements. + * + * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular + * HTML element throughout the page. + */ +body { + background-color:var(--body-background-color); + color:var(--body-text-color); + font-family:var(--body-font-family); + font-size:var(--body-font-size); + margin:0; + padding:0; + height:100%; + width:100%; +} +main [id] { + scroll-margin-top: calc(var(--nav-height) + 6px); +} +div.main-grid { + max-width: var(--max-content-width); + margin: var(--content-margin); +} +a:link, a:visited { + text-decoration:none; + color:var(--link-color); +} +nav a:link, nav a:visited { + color: var(--subnav-link-color); +} +a[href]:hover, a[href]:active { + text-decoration:none; + color:var(--link-color-active); +} +pre { + font-family:var(--code-font-family); + font-size:var(--code-font-size); + line-height: var(--code-line-height); + background-color: var(--pre-background-color); + color: var(--pre-text-color); + padding: 10px; + overflow-x:auto; +} +h1 { + font-size:1.425em; +} +h2 { + font-size:1.28em; +} +h3 { + font-size:1.14em; +} +h4 { + font-size:1.072em; +} +h5 { + font-size:1.001em; +} +h6 { + font-size:0.93em; +} +/* Disable font boosting for selected elements */ +h1, h2, h3, h4, h5, h6, div.member-signature, div.member-signature > span { + max-height: 1000em; +} +ul { + list-style-type:disc; +} +tt { + font-family:var(--code-font-family); +} +code { + font-family:var(--code-font-family); + font-size:var(--code-font-size); +} +button { + font-family: var(--body-font-family); + font-size: 1em; +} +hr { + border-color: #aaa; +} +/* + * Styles for HTML generated by javadoc. + * + * These are style classes that are used by the standard doclet to generate HTML documentation. + */ + +/* + * Styles for document title and copyright. + */ +.about-language { + flex: 0 0 auto; + padding:0 20px; + margin:0; + font-size:0.915em; + max-width: 50%; + white-space: nowrap; +} +.legal-copy { + font-family: var(--body-font-family); + line-height: normal; +} +/* + * Styles for navigation bar. + */ +@media screen { + header { + position:sticky; + top:0; + z-index:2; + background: var(--body-background-color); + } +} +.nav-content { + display:flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 100%; + max-width: var(--max-content-width); + margin: var(--content-margin); +} +.top-nav { + background-color:var(--navbar-background-color); + color:var(--navbar-text-color); + width:100%; + height:var(--top-nav-height); + overflow:visible; + font-size:0.857em; + position:relative; +} +.top-nav nav.toc { + display: none; + flex-direction: column; +} +.top-nav nav.toc button.show-sidebar, +.top-nav nav.toc button.hide-sidebar { + display: none; +} +button#navbar-toggle-button { + display:none; +} +ul.nav-list { + display:inline-flex; + margin:0; + padding-left:4px; + flex: 1 1 auto; + white-space: nowrap; +} +ul.nav-list li { + list-style:none; + padding: 5px 6px; + text-transform:uppercase; + height: 1.2em; +} +div.sub-nav { + background-color:var(--subnav-background-color); + width:100%; + overflow:hidden; + font-size:var(--nav-font-size); + height: var(--sub-nav-height); +} +ol.sub-nav-list { + flex: 1 1 90%; + line-height: 1.8; + display: inline-flex; + overflow: auto; + scroll-snap-type: x mandatory; + scroll-padding-left: 13px; + scrollbar-width: none; + padding-left:6px; + white-space: nowrap; + margin:0; +} +ol.sub-nav-list::-webkit-scrollbar { + display: none; +} +ol.sub-nav-list li { + list-style:none; + scroll-snap-align: start; +} +ol.sub-nav-list li:not(:first-child) { + background: url("right.svg") no-repeat 3px; + background-size: 10px; + padding-left: 17px; + list-style: none; +} +ol.sub-nav-list a { + padding: 3px; +} +ol.sub-nav-list a.current-selection { + background-color: var(--toc-background-color); + border-radius: 3px; +} +.sub-nav .nav-list-search { + flex: 1 1 10%; + margin: 0 15px; + position:relative; + white-space: nowrap; +} +.top-nav .nav-list a:link, .top-nav .nav-list a:active, .top-nav .nav-list a:visited { + color:var(--navbar-text-color); + text-decoration:none; + text-transform:uppercase; +} +.top-nav .nav-list a:hover { + color:var(--link-color-active); +} +.nav-bar-cell1-rev { + background-color:var(--selected-background-color); + color:var(--selected-text-color); + margin: 0 5px; + border-radius: 1px; +} +.skip-nav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* + * Styles for page header. + */ +.title { + color:var(--title-color); + margin:10px 0 12px 0; +} +.sub-title { + margin:5px 0 0 0; +} +ul.contents-list { + margin: 0 0 15px 0; + padding: 0; + list-style: none; +} +ul.contents-list li { + font-size:0.93em; +} +/* + * Styles for headings. + */ +body.class-declaration-page .summary h2, +body.class-declaration-page .details h2, +body.class-use-page h2, +body.module-declaration-page .block-list h2 { + font-style: italic; + padding:0; + margin:15px 0; + overflow-x:auto; +} +body.class-use-page h2 { + margin-top: 20px; +} +body.class-declaration-page .details h3 { + background-color:var(--member-heading-background-color); + border:1px solid var(--border-color); + margin:6px 0; + padding:7px; + overflow-x:auto; + font-size: 1.08em; +} +body.class-declaration-page section.detail:target > h3, +body.class-declaration-page section.detail > h3:target { + background-color: var(--navbar-background-color); + color: var(--navbar-text-color); +} +body.class-declaration-page section.detail:target > h3 > a.anchor-link > img, +body.class-declaration-page section.detail > h3:target > a.anchor-link > img { + filter: invert(100%) sepia(4%) saturate(98%) hue-rotate(212deg) brightness(160%) contrast(160%); +} +h1 > sup { + font-size: small; +} +/* + * Styles for page layout containers. + */ +.main-grid { + display: flex; + flex-direction: row; +} +.main-grid main { + flex: 3.2 1 0; + min-width: 240px +} +.main-grid nav.toc { + flex: 1 1 0; + min-width: 240px; +} +main { + padding:10px 25px; + position:relative; +} +/* Compensate for non-collapsing margins between element description and summary tables */ +div.horizontal-scroll > section[id$=-description] > :is(dl, ol, ul, p, div, blockquote, pre):last-child, +div.horizontal-scroll > section[id$=-description] > :last-child > :is(li, dd):last-child, +section.class-description > div.horizontal-scroll > :is(dl, ol, ul, p, div, blockquote, pre):last-child, +section.class-description > div.horizontal-scroll > :last-child > :is(li, dd):last-child { + margin-bottom:4px; +} +dl.notes > dt { + font-family: var(--body-font-family); + font-size:0.856em; + font-weight:bold; + margin:10px 0 0 0; + color:var(--body-text-color); +} +dl.notes > dd { + margin:6px 10px 10px 15px; + font-size:var(--block-font-size); + font-family:var(--block-font-family); + line-height:var(--block-line-height); +} +dl.notes > dd > ul, dl.notes > dd > ol { + margin-bottom: 1em; + margin-top: 1em; +} +dl.name-value > dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +dl.name-value > dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* + * Styles for table of contents. + */ +.main-grid nav.toc { + background-color: var(--toc-background-color); + position: sticky; + top: calc(var(--nav-height)); + max-height: calc(100vh - var(--nav-height)); + display: flex; + flex-direction: column; + font-family: var(--body-font-family); + z-index: 1; +} +.main-grid nav.toc div.toc-header { + top: var(--nav-height); + z-index: 1; + padding: 15px 20px; +} +.main-grid nav.toc > ol.toc-list { + max-height: calc(100vh - var(--nav-height) - 100px); + padding-left: 12px; +} +.main-grid nav.toc button { + position: absolute; + bottom: 16px; + z-index: 3; + background-color: var(--toc-background-color); + color: #666666; + font-size: 0.76rem; + border: none; + cursor: pointer; + padding: 6px 10px; + white-space: nowrap; +} +.main-grid nav.toc button > img { + vertical-align: middle; + width: 16px; + height: 16px; +} +.main-grid nav.toc button.hide-sidebar { + right: 0; +} +.main-grid nav.toc button.show-sidebar { + left: 0; + display: none; +} +.main-grid nav.toc button span { + display: none; +} +.main-grid nav.toc button:hover, +.main-grid nav.toc button:focus { + color: var(--body-text-color); + border: 1px solid var(--subnav-background-color); +} +.main-grid nav.toc button:active { + background-color: var(--subnav-background-color); + color: var(--link-color-active); +} +.main-grid nav.toc button:hover span, +.main-grid nav.toc button:focus span { + display: inline; +} +.main-grid nav.toc button:hover, +.main-grid nav.toc button:focus { + box-shadow: 1px 1px 5px rgba(0,0,0,0.2); +} +.main-grid nav.toc.hide-sidebar { + min-width: revert; + background-color: var(--body-background-color); + max-width: 20px; +} +.main-grid nav.toc.hide-sidebar div.toc-header, +.main-grid nav.toc.hide-sidebar ol.toc-list, +.main-grid nav.toc.hide-sidebar button.hide-sidebar { + display: none; +} +.main-grid nav.toc.hide-sidebar button.show-sidebar { + display: inline; +} +nav.toc div.toc-header { + padding: 15px; + display: inline-flex; + align-items: center; + color: var(--body-text-color); + font-size: 0.856em; + font-weight: bold; + white-space: nowrap; + overflow-x: hidden; + position: sticky; + min-height: 20px; +} +nav.toc > ol.toc-list { + overflow: hidden auto; + overscroll-behavior: contain; +} +nav.toc ol.toc-list { + list-style: none; + font-size: var(--nav-font-size); + padding-left: 0; + margin: 0; +} +a.current-selection { + font-weight: bold; +} +nav.toc a { + display: block; + padding: 8px; + overflow: hidden; + text-overflow: ellipsis; +} +nav.toc ol.toc-list ol.toc-list a { + padding-left: 24px; +} +nav.toc ol.toc-list ol.toc-list ol.toc-list a { + padding-left: 40px; +} +nav.toc a:hover { + background-color: var(--toc-hover-color); +} +nav.toc a.current-selection { + background-color: var(--toc-highlight-color); +} +nav.toc a:focus-visible { + background-color: var(--selected-background-color); + color: var(--selected-text-color); + outline: none; +} +/* + * Styles for lists. + */ +ul.details-list .block > ul, +ul.details-list .notes dd > ul { + margin: 12px 0; +} +li.circle { + list-style:circle; +} +ul.horizontal li { + display:inline; + font-size:0.9em; +} +div.inheritance div.inheritance { + margin-left:2em; +} +main > div.inheritance { + overflow-x:auto; +} +ul.block-list, +ul.details-list, +ul.member-list, +ul.summary-list { + margin:4px 0 10px 0; + padding:0; +} +ul.block-list > li, +ul.details-list > li, +ul.member-list > li, +ul.summary-list > li { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +ul.ref-list { + padding:0; + margin:0; +} +ul.ref-list > li { + list-style:none; +} +.summary-table dl, .summary-table dl dt, .summary-table dl dd { + margin-top:0; + margin-bottom:1px; +} +dl.notes > dd > ul.tag-list, dl.notes > dd > ul.tag-list-long { + padding-left: 0; + margin: 0; + list-style: none; +} +ul.tag-list li { + display: inline; +} +ul.tag-list li:not(:last-child):after, +ul.tag-list-long li:not(:last-child):after +{ + content: ", "; + white-space: pre-wrap; +} +ul.preview-feature-list { + list-style: none; + margin:0; + padding:0.1em; + line-height: 1.6; +} +ul.preview-feature-list input { + margin-right: 8px; +} +/* + * Styles for tables. + */ +.summary-table, .details-table { + border:1px solid var(--border-color); + border-top:0; + padding:0; + margin-bottom: 14px; +} +.caption { + overflow: auto hidden; + padding: 8px 0 0 1px; +} +.caption span, +.inherited-list h3 { + font-size: 0.98em; + font-weight:bold; + white-space:nowrap; + border-radius: var(--tab-border-radius); + margin: 0; +} +.caption span { + background-color: var(--navbar-background-color); + padding:5px 12px 7px 12px; + height:16px; + color:var(--navbar-text-color); + display:inline-block; +} +.inherited-list h3 { + background-color: var(--subnav-background-color); + padding:6px 12px 7px 12px; + height:17px; + width: fit-content; + max-width: 93%; +} +/* Background required for captions with links */ +.class-use-page .caption span, +.package-use-page .caption span, +.constants-summary-page .caption span, +.inherited-list h3 { + background-color: var(--subnav-background-color); + color: var(--block-text-color); +} +.caption a:link, +.caption a:visited, +.inherited-list h3 a:link, +.inherited-list h3 a:visited { + color:var(--subnav-link-color); +} +div.table-tabs { + padding: 8px 0 0 1px; + white-space: nowrap; + overflow-x: auto; +} +div.table-tabs > button { + font-size: 0.98em; + border: none; + cursor: pointer; + padding: 6px 12px; + font-weight: bold; + margin-right: 8px; + border-radius: var(--tab-border-radius); +} +div.table-tabs > .active-table-tab { + background: var(--selected-background-color); + color: var(--selected-text-color); +} +div.table-tabs > button.table-tab { + background: var(--navbar-background-color); + color: var(--navbar-text-color); +} +.two-column-search-results { + display: grid; + grid-template-columns: minmax(400px, max-content) minmax(400px, auto); +} +div.checkboxes { + line-height: 2; +} +div.checkboxes > span { + margin-left: 10px; +} +div.checkboxes > label { + margin-left: 8px; + white-space: nowrap; +} +div.checkboxes > label > input { + margin: 0 6px 0 2px; +} +.two-column-summary { + display: grid; + grid-template-columns: minmax(25%, max-content) minmax(25%, auto); +} +.three-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(20%, max-content) minmax(20%, auto); +} +.three-column-release-summary { + display: grid; + grid-template-columns: minmax(40%, max-content) minmax(10%, max-content) minmax(40%, auto); +} +.four-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, max-content) minmax(15%, auto); +} +@media screen and (max-width: 1000px) { + .four-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); + } +} +@media screen and (max-width: 800px) { + .two-column-search-results { + display: grid; + grid-template-columns: minmax(40%, max-content) minmax(40%, auto); + } + .three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(25%, auto); + } + .three-column-release-summary { + display: grid; + grid-template-columns: minmax(70%, max-content) minmax(30%, max-content) + } + .three-column-summary .col-last, + .three-column-release-summary .col-last{ + grid-column-end: span 2; + } +} +@media screen and (max-width: 600px) { + .two-column-summary { + display: grid; + grid-template-columns: 1fr; + } +} +.summary-table > div, .details-table > div { + font-size: var(--nav-font-size); + line-height: 1.6; + padding: 8px 3px 3px 7px; + overflow: auto hidden; +} +.summary-table > div.table-header, .details-table > div.table-header { + font-size: 0.92em; + line-height: 1.2; + height: 18px; +} +.table-header { + background: var(--table-header-color); + font-weight: bold; + border-bottom: 1px solid var(--border-color); +} +/* Sortable table columns */ +.table-header[onclick] { + cursor: pointer; +} +.table-header[onclick]::after { + content:""; + display:inline-block; + background-image:url('data:image/svg+xml; utf8, \ + \ + '); + background-size:100% 100%; + width:9px; + height:14px; + margin-left:4px; + margin-bottom:-3px; +} +.table-header[onclick].sort-asc::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); + +} +.table-header[onclick].sort-desc::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); +} +.col-first, .col-second, .col-constructor-name { + overflow: auto; +} +body:not(.class-declaration-page) .col-first a:link, +.col-summary-item-name a:link { + font-weight:bold; +} +.even-row-color { + background-color:var(--even-row-color); +} +.odd-row-color { + background-color:var(--odd-row-color); +} +/* + * Styles for contents. + */ +div.block { + font-size:var(--block-font-size); + font-family:var(--block-font-family); + line-height:var(--block-line-height); +} +.module-signature, +.package-signature, +.type-signature, +.member-signature { + font-family:var(--code-font-family); + font-size:var(--code-font-size); + margin:8px 0 14px 0; + white-space: pre-wrap; +} +.module-signature, +.package-signature, +.type-signature { + margin-top: 0; +} +.member-signature .parameters, +.member-signature .exceptions { + display: inline-block; + vertical-align: top; + white-space: pre-wrap; +} +.member-signature .type-parameters { + white-space: pre-wrap; +} +:is(h1, h2, h3, h4, h5, h6, sup, sub, small, big) code, +[style*=font-size] code { + font-size: inherit; +} +.doc-file-page main { + font-family: var(--block-font-family); + font-size: var(--block-font-size); + line-height: var(--block-line-height); +} +.doc-file-page main footer { + font-family: var(--body-font-family); + font-size: var(--body-font-size); +} +.tree-page .hierarchy, +.package-tree-page .hierarchy { + line-height: 1.4; +} +/* + * Styles for formatting effect. + */ +.source-line-no { + /* Color of line numbers in source pages can be set via custom property below */ + color:var(--source-linenumber-color, green); + padding:0 30px 0 0; +} +.block { + display:block; + margin:0 10px 5px 0; + color:var(--block-text-color); +} +.deprecated-label, .description-from-type-label, .implementation-label, .member-name-link, +.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label, +.restricted-label { + font-weight:bold; +} +sup.preview-mark, +sup.restricted-mark { + font-family: var(--code-font-family); + font-weight: normal; + font-size: 8px; + background-color: var(--mark-background-color); + padding: 1px; + border-radius: 2px; +} +sup.preview-mark > a:link, +sup.restricted-mark > a:link { + font-weight: normal; +} +.deprecation-comment, .help-footnote, .preview-comment, .restricted-comment { + font-style:italic; +} +.deprecation-block, .preview-block, .restricted-block { + font-size:1em; + font-family:var(--block-font-family); + border-style:solid; + border-width:thin; + border-radius:6px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +.deprecation-block code, .preview-block code, .restricted-block code { + font-size: 0.97em; +} +div.block div.deprecation-comment { + font-style:normal; +} +details.invalid-tag, span.invalid-tag { + font-size:1em; + font-family:var(--block-font-family); + color: var(--invalid-tag-text-color); + background: var(--invalid-tag-background-color); + border: thin solid var(--table-border-color); + border-radius:2px; + padding: 2px 4px; + display:inline-block; +} +details summary { + cursor: pointer; +} +/* + * Styles specific to HTML5 elements. + */ +main, nav, header, footer, section { + display:block; +} +/* + * Styles for javadoc search. + */ +.ui-menu .ui-state-active { + /* Overrides the color of selection used in jQuery UI */ + background: var(--selected-background-color); + color: var(--selected-text-color); + /* Workaround for browser bug, see JDK-8275889 */ + margin: -1px 0; + border-top: 1px solid var(--selected-background-color); + border-bottom: 1px solid var(--selected-background-color); +} +.ui-autocomplete-category { + font-weight:bold; + font-size:15px; + padding:7px 8px; + background-color:var(--navbar-background-color); + color:var(--navbar-text-color); + box-sizing: border-box; +} +.ui-autocomplete { + max-height:calc(98vh - var(--nav-height)); + max-width:min(75vw, calc(var(--max-content-width) * 0.748)); + overflow-y:auto; + white-space:nowrap; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); + overscroll-behavior: contain; +} +ul.ui-autocomplete { + position:fixed; + z-index:10; + background-color: var(--body-background-color); +} +ul.ui-autocomplete li { + float:left; + clear:both; + min-width:100%; + box-sizing: border-box; +} +ul.ui-autocomplete li.ui-static-link { + position:sticky; + bottom:0; + left:0; + background: var(--subnav-background-color); + padding: 5px 0; + font-family: var(--body-font-family); + font-size: 0.93em; + font-weight: bold; + z-index: 10; +} +li.ui-static-link a, li.ui-static-link a:visited { + text-decoration:none; + color:var(--link-color); + float:right; + margin-right:20px; +} +.ui-autocomplete > li.result-item:nth-child(even) { + background-color: var(--even-row-color) +} +.ui-autocomplete > li.result-item:nth-child(odd) { + background-color: var(--odd-row-color) +} +.ui-autocomplete { + display: grid; + grid-template-columns: auto auto; +} +.ui-autocomplete > li, +.ui-autocomplete > li > div { + grid-column: 1 / 3; +} +.ui-autocomplete > li.result-item, +.ui-autocomplete > li.result-item > div { + display: grid; + grid-template-columns: subgrid; +} +.ui-autocomplete > li.result-item { + font-family: var(--body-font-family); + font-size: var(--body-font-size); + line-height: 1.7; +} +.ui-autocomplete .search-result-label { + padding: 1px 4px; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-autocomplete .search-result-desc { + font-size: var(--nav-font-size); + padding: 2px 4px; + color: #404040; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-autocomplete .result-highlight { + font-weight:bold; +} +.ui-menu .ui-state-active .search-result-desc { + color: #383838; +} +.ui-menu .ui-menu-item-wrapper { + padding: 3px 4px; +} +input[type="text"] { + background-image:url('glass.svg'); + background-size:13px; + background-repeat:no-repeat; + background-position:3px 4px; + background-color: var(--search-input-background-color); + color: var(--search-input-text-color); + border-color: var(--border-color); + border-radius: 4px; + padding-left:20px; + padding-right: 18px; + font-size: var(--nav-font-size); + height: 19px; +} +input#page-search-input { + width: calc(180px + 10vw); + margin: 10px 0; +} +input#search-input { + width: 270px; + margin: 0; +} +input.filter-input { + min-width: 40px; + width: 180px; + margin: 0 -8px 0 5px; +} +input#reset-search, input.reset-filter, input#page-search-reset { + background-color: transparent; + background-image:url('x.svg'); + background-repeat:no-repeat; + background-size:contain; + border:0; + border-radius:0; + width:12px; + height:12px; + min-width:12px; + min-height:12px; + font-size:0; + visibility:hidden; +} +input#reset-search { + position:absolute; + right:5px; + top:7px; +} +input.reset-filter { + position: relative; + right: 10px; + top: 0; +} +input#page-search-reset { + position: relative; + right: 18px; + top: -5px; +} +input::placeholder { + color:var(--search-input-placeholder-color); + opacity: 1; +} +input:focus::placeholder { + color: transparent; +} +select#search-modules { + margin: 0 10px 10px 2px; + font-size: var(--nav-font-size); + padding: 3px 5px; + border-radius: 4px; + background: #f0f0f0; + border: 1px solid #909090; +} +kbd { + background-color: #eeeeee; + border: 1px solid #b0b0b0; + border-radius: 3px; + padding: 0 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 2px 0 0 rgba(255, 255, 255, 0.6) inset; + font-size: 0.9em; + font-weight: bold; +} +.search-tag-result:target { + background-color:var(--search-tag-highlight-color); +} +dd > span:target, +h1 > span:target { + background-color: var(--search-tag-highlight-color); +} +section.class-description dd > span:target, +section.class-description h1 > span:target { + scroll-margin-top: 20em; +} +details.page-search-details { + display: inline-block; +} +div#result-container { + font-size: 1em; +} +#result-container .result-highlight { + font-weight:bold; +} +#result-container div.result-table { + display: grid; + grid-template-columns: minmax(40%, max-content) minmax(40%, auto); +} +#result-container div.result-table > div.table-header, +#result-container div.result-table > a.search-result-link { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / 3; + margin: 0; +} +#result-container div.result-table > div.table-header > span { + padding: 5px 12px; + font-size: 0.93em; + background-color: var(--subnav-background-color); +} +#result-container div.result-table > a.search-result-link > span { + padding: 8px 12px; +} +#result-container div.result-table > a.search-result-link:nth-child(odd) { + background-color: var(--odd-row-color) +} +#result-container div.result-table > a.search-result-link:nth-child(even) { + background-color: var(--even-row-color) +} +#result-container div.result-table > a.search-result-link { + color: var(--block-text-color); + white-space: nowrap; +} +#result-container div.result-table > a.search-result-link:focus-visible, +#result-container div.result-table > a.search-result-link.selected { + background-color: var(--selected-background-color); + outline: none; +} +#result-container div.result-table > a.search-result-link .search-result-label { + overflow: hidden; + text-overflow: ellipsis; +} +#result-container div.result-table > a.search-result-link .search-result-desc { + font-size: var(--nav-font-size); + color: #404040; + overflow: hidden; + text-overflow: ellipsis; +} +.page-search-info { + background-color: var(--subnav-background-color); + border-radius: 3px; + border: 0 solid var(--border-color); + padding: 0 8px; + margin: 8px 0; + overflow: hidden; + display: none; + transition: all 0.2s ease; +} +div.table-tabs > button.table-tab { + background: var(--navbar-background-color); + color: var(--navbar-text-color); +} +.page-search-header { + padding: 5px 12px 7px 12px; + font-weight: bold; + margin-right: 3px; + background-color:var(--navbar-background-color); + color:var(--navbar-text-color); + display: inline-block; +} +button.page-search-header { + border: none; + cursor: pointer; +} +span#page-search-link { + text-decoration: underline; +} +.module-graph span, .sealed-graph span { + display:none; + position:absolute; +} +.module-graph:hover span, .sealed-graph:hover span { + display:block; + margin: -100px 0 0 100px; + z-index: 5; +} +.horizontal-scroll { + overflow: auto hidden; +} +section.class-description { + line-height: 1.4; +} +.summary section[class$="-summary"], .details section[class$="-details"] { + margin-bottom: 24px; + background-color: var(--section-background-color); +} +body.class-uses section.detail { + padding: 0 25px 5px 10px; + margin: 25px 0; +} +section.serialized-class-details { + padding: 0 20px 5px 10px; + border: 1px solid var(--border-color); + background-color: var(--detail-block-color); +} +section.serialized-class-details .detail { + overflow: auto; + padding-left: 12px; +} +section[class$="-details"] .detail { + background-color:var(--detail-background-color); +} +section[class$="-details"] .detail > div { + padding-left: 8px; +} +.inherited-list { + margin: 20px 0; + background-color:var(--detail-background-color); +} +.inherited-list > code { + padding: 8px; + display: block; + background-color: var(--code-background-color); + border-radius: 0; + line-height: var(--code-line-height); +} +.vertical-separator { + padding: 0 5px; +} +.help-section { + font-size: var(--block-font-size); + line-height: var(--block-line-height); +} +ul.help-section-list { + margin: 0; +} +ul.help-subtoc > li { + display: inline-block; + padding-right: 5px; + font-size: smaller; +} +ul.help-subtoc > li::before { + content: "\2022" ; + padding-right:2px; +} +.help-note { + font-style: italic; +} +/* + * Indicator icon for external links. + */ +main a[href*="://"]::after { + content:""; + display:inline-block; + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); + background-size:100% 100%; + width:7px; + height:7px; + margin-left:2px; + margin-bottom:4px; +} +main a[href*="://"]:hover::after, +main a[href*="://"]:focus::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); +} +/* + * Styles for header/section anchor links + */ +a.anchor-link { + opacity: 0; + transition: opacity 0.1s 0.1s; +} +:hover > a.anchor-link { + opacity: 90%; +} +a.anchor-link:hover, +a.anchor-link:focus-visible, +a.anchor-link.visible { + opacity: 100%; +} +a.anchor-link > img { + width: 0.9em; + height: 0.9em; +} +/* + * Styles for copy-to-clipboard buttons + */ +button.copy { + font-size: var(--nav-font-size); + line-height: 1.2; + padding:0.3em; + background-color: transparent; + border: 1px solid transparent; + border-radius: 3px; + position: relative; + opacity: 80%; + transition: all 0.1s ease; + cursor: pointer; +} +button.copy:hover, +button.copy:active, +button.copy:focus, +button.copy.visible { + opacity: 100%; + background-color: inherit; + border-color: var(--button-border-color); + filter: var(--button-focus-filter); +} +button.copy:active { + filter: var(--button-active-filter); +} +button.copy img { + position: relative; +} +button.copy span { + color: var(--body-text-color); + position: relative; + padding: 0.2em; + top: -0.1em; + transition: opacity 0.1s ease; + opacity: 0; +} +button.copy:hover span, +button.copy:focus span, +button.copy.visible span { + opacity: 100%; +} +/* search page copy button */ +button#page-search-copy { + margin-left: 0.4em; + top:0.13em; +} +button#page-search-copy img { + width: 1.2em; + height: 1.2em; + padding: 0.01em 0; + top: 0.15em; +} +button#page-search-copy span { + top: -0.18em; +} +/* snippet copy button */ +button.snippet-copy { + position: absolute; + top: 4px; + right: 1px; + height: 32px; +} +button.snippet-copy img { + width: 18px; + height: 18px; + padding: 2px 0; +} +button.snippet-copy span { + top: -7px; +} +/* + * Styles for user-provided tables. + * + * borderless: + * No borders, vertical margins, styled caption. + * This style is provided for use with existing doc comments. + * In general, borderless tables should not be used for layout purposes. + * + * plain: + * Plain borders around table and cells, vertical margins, styled caption. + * Best for small tables or for complex tables for tables with cells that span + * rows and columns, when the "striped" style does not work well. + * + * striped: + * Borders around the table and vertical borders between cells, striped rows, + * vertical margins, styled caption. + * Best for tables that have a header row, and a body containing a series of simple rows. + */ + +table.borderless, +table.plain, +table.striped { + margin-top: 10px; + margin-bottom: 10px; +} +table.borderless > caption, +table.plain > caption, +table.striped > caption { + font-weight: bold; + font-size: smaller; +} +table.borderless th, table.borderless td, +table.plain th, table.plain td, +table.striped th, table.striped td { + padding: 2px 5px; +} +table.borderless, +table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, +table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { + border: none; +} +table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { + background-color: transparent; +} +table.plain { + border-collapse: collapse; + border: 1px solid var(--table-border-color); +} +table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { + background-color: transparent; +} +table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, +table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { + border: 1px solid var(--table-border-color); +} +table.striped { + border-collapse: collapse; + border: 1px solid var(--table-border-color); +} +table.striped > thead { + background-color: var(--subnav-background-color); +} +table.striped > thead > tr > th, table.striped > thead > tr > td { + border: 1px solid var(--table-border-color); +} +table.striped > tbody > tr:nth-child(even) { + background-color: var(--odd-row-color) +} +table.striped > tbody > tr:nth-child(odd) { + background-color: var(--even-row-color) +} +table.striped > tbody > tr > th, table.striped > tbody > tr > td { + border-left: 1px solid var(--table-border-color); + border-right: 1px solid var(--table-border-color); +} +table.striped > tbody > tr > th { + font-weight: normal; +} +/** + * Media queries for responsive design + */ +@media (prefers-reduced-motion: reduce) { + :root { + scroll-behavior: auto; + } +} +@media screen and (max-width: 1200px) { + input#search-input { + width: 22.5vw; + } +} +@media screen and (max-width: 1000px) { + .main-grid nav.toc { + display: none; + } + .top-nav nav.toc { + display: none; + position: absolute; + top: var(--top-nav-height); + left: 40vw; + width: 60vw; + z-index: 7; + background-color: var(--toc-background-color); + box-sizing: border-box; + } + .top-nav nav.toc div.toc-header { + padding: 6px 15px; + font-size: 0.94em; + background-color: var(--toc-background-color); + top: calc(var(--top-nav-height) + 10px); + } + .top-nav nav.toc ol.toc-list li { + font-size: 1.04em; + } + nav.toc a:link, nav.toc a:visited { + text-decoration:none; + color:var(--link-color); + } + nav.toc a[href]:hover, nav.toc a[href]:focus { + text-decoration:none; + color:var(--link-color-active); + } + :root { + scroll-behavior: auto; + } + header { + max-height: 100vh; + overflow-y: visible; + overscroll-behavior: contain; + } + nav { + overflow: visible; + } + ul.nav-list { + display: none; + position: absolute; + top: var(--top-nav-height); + overflow: auto; + z-index: 7; + background-color: var(--navbar-background-color); + width: 40%; + padding: 0; + box-sizing: border-box; + } + ul.nav-list li { + float: none; + padding: 6px; + margin-left: 10px; + margin-top: 2px; + } + .top-nav a:link, .top-nav a:active, .top-nav a:visited { + display: block; + } + .top-nav div.nav-menu-button { + flex: 1 1 auto; + } + .sub-nav ol.sub-nav-list { + margin-left: 4px; + padding-left: 4px; + } + button#navbar-toggle-button { + width: 3.4em; + height: 2.8em; + background-color: transparent; + display: block; + border: 0; + margin: 0 10px; + cursor: pointer; + font-size: 10px; + } + button#navbar-toggle-button .nav-bar-toggle-icon { + display: block; + width: 24px; + height: 3px; + margin: 4px 0; + border-radius: 2px; + background-color: var(--navbar-text-color); + } + button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(1) { + transform: rotate(45deg); + transform-origin: 10% 10%; + width: 26px; + } + button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(2) { + opacity: 0; + } + button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(3) { + transform: rotate(-45deg); + transform-origin: 10% 90%; + width: 26px; + } + .ui-autocomplete { + display: block; + grid-template-columns: none; + } + .ui-autocomplete > li, + .ui-autocomplete > li > div, + .ui-autocomplete > li.result-item, + .ui-autocomplete > li.result-item > div { + grid-column: unset; + display: block; + grid-template-columns: none; + } + .ui-autocomplete > li.result-item { + line-height: 1.45; + } + .ui-autocomplete .search-result-label { + display: block; + } + .ui-autocomplete .search-result-desc { + display: block; + } +} +@media screen and (max-width: 800px) { + .about-language { + padding: 0 16px; + max-width: 90%; + } + ul.nav-list li { + margin-left: 5px; + } + main { + padding: 10px 12px; + } + body { + -webkit-text-size-adjust: none; + } +} +@media screen and (max-width: 600px) { + .nav-list-search > a { + display: none; + } + .member-signature { + white-space: pre-line; + } + .member-signature .annotations { + white-space: pre-wrap; + } + input#search-input { + width: 18vw; + } + .inherited-list h3 { + overflow: auto clip; + } + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0; + } +} +pre.snippet { + background-color: var(--snippet-background-color); + color: var(--snippet-text-color); + padding: 12px; +} +div.snippet-container { + position: relative; + padding-right: 30px; + background-color: var(--snippet-background-color); +} +pre.snippet .italic { + font-style: italic; +} +pre.snippet .bold { + font-weight: bold; +} +pre.snippet .highlighted { + background-color: var(--snippet-highlight-color); + border-radius: 10%; +} +/* + * Hide navigation links and search box in print layout + */ +@media print { + ul.nav-list, div.sub-nav, .main-grid nav.toc, button.copy { + display:none; + } +} diff --git a/docs/Javadoc/apidocs/resource-files/x.svg b/docs/Javadoc/apidocs/resource-files/x.svg new file mode 100644 index 00000000..1efb4109 --- /dev/null +++ b/docs/Javadoc/apidocs/resource-files/x.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/docs/Javadoc/apidocs/script-files/jquery-3.7.1.min.js b/docs/Javadoc/apidocs/script-files/jquery-3.7.1.min.js new file mode 100644 index 00000000..7f37b5d9 --- /dev/null +++ b/docs/Javadoc/apidocs/script-files/jquery-3.7.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0{"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(x){x.ui=x.ui||{};x.ui.version="1.14.1";var n,s,C,k,o,l,a,r,u,i,h=0,c=Array.prototype.hasOwnProperty,d=Array.prototype.slice;x.cleanData=(n=x.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove");n(t)}),x.widget=function(t,i,e){var s,n,o,l,a={},r=t.split(".")[0];return"__proto__"===(t=t.split(".")[1])||"constructor"===t?x.error("Invalid widget name: "+t):(l=r+"-"+t,e||(e=i,i=x.Widget),Array.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr.pseudos[l.toLowerCase()]=function(t){return!!x.data(t,l)},x[r]=x[r]||{},s=x[r][t],n=x[r][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},x.extend(n,s,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(o=new i).options=x.widget.extend({},o.options),x.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}a[e]="function"!=typeof s?s:function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}}),n.prototype=x.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},a,{constructor:n,namespace:r,widgetName:t,widgetFullName:l}),s?(x.each(s._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),x.widget.bridge(t,n),n)},x.widget.extend=function(t){for(var e,i,s=d.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n{var i=[];n.element.each(function(t,e){x.map(l.classesElementLookup,function(t){return t}).some(function(t){return t.is(e)})||i.push(e)}),l._on(x(i),{remove:"_untrackClassesElement"})})(),x(x.uniqueSort(i.get().concat(n.element.get())))):x(i.not(n.element).get()),l.classesElementLookup[t[s]]=i,o.push(t[s]),e&&n.classes[t[s]]&&o.push(n.classes[t[s]])}return(n=x.extend({element:this.element,classes:this.options.classes||{}},n)).keys&&t(n.keys.match(/\S+/g)||[],!0),n.extra&&t(n.extra.match(/\S+/g)||[]),o.join(" ")},_untrackClassesElement:function(i){var s=this;x.each(s.classesElementLookup,function(t,e){-1!==x.inArray(i.target,e)&&(s.classesElementLookup[t]=x(e.not(i.target).get()))}),this._off(x(i.target))},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){var n="string"==typeof t||null===t,e={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s="boolean"==typeof s?s:i};return e.element.toggleClass(this._classes(e),s),this},_on:function(n,o,t){var l,a=this;"boolean"!=typeof n&&(t=o,o=n,n=!1),t?(o=l=x(o),this.bindings=this.bindings.add(o)):(t=o,o=this.element,l=this.widget()),x.each(t,function(t,e){function i(){if(n||!0!==a.options.disabled&&!x(this).hasClass("ui-state-disabled"))return("string"==typeof e?a[e]:e).apply(a,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||x.guid++);var t=t.match(/^([\w:-]*)\s*(.*)$/),s=t[1]+a.eventNamespace,t=t[2];t?l.on(s,t,i):o.on(s,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e),this.bindings=x(this.bindings.not(t).get()),this.focusable=x(this.focusable.not(t).get()),this.hoverable=x(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(x(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(x(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,n,o=this.options[t];if(i=i||{},(e=x.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],n=e.originalEvent)for(s in n)s in e||(e[s]=n[s]);return this.element.trigger(e,i),!("function"==typeof o&&!1===o.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},x.each({show:"fadeIn",hide:"fadeOut"},function(o,l){x.Widget.prototype["_"+o]=function(e,t,i){var s,n=(t="string"==typeof t?{effect:t}:t)?!0!==t&&"number"!=typeof t&&t.effect||l:o;"number"==typeof(t=t||{})?t={duration:t}:!0===t&&(t={}),s=!x.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&x.effects&&x.effects.effect[n]?e[o](t):n!==o&&e[n]?e[n](t.duration,t.easing,i):e.queue(function(t){x(this)[o](),i&&i.call(e[0]),t()})}}),x.widget;function E(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function T(t,e){return parseInt(x.css(t,e),10)||0}function W(t){return null!=t&&t===t.window}C=Math.max,k=Math.abs,o=/left|center|right/,l=/top|center|bottom/,a=/[\+\-]\d+(\.[\d]+)?%?/,r=/^\w+/,u=/%$/,i=x.fn.position,x.position={scrollbarWidth:function(){var t,e,i;return void 0!==s?s:(i=(e=x("
")).children()[0],x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i)},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(k(s),k(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})):i.apply(this,arguments)},x.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,s=s.width,o=t.left-e.collisionPosition.marginLeft,l=n-o,a=o+e.collisionWidth-s-n;s",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(this.document[0].activeElement);!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active)&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]!==i[0])||i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),t=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(t,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),e=(i=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(i,"ui-menu-item")._addClass(e,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(e=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,i=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-e-i,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&"true"===this.element.prop("contentEditable"),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)i=!1,this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault();else if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){n?(n=!1,t.preventDefault()):this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
    ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent)&&/^mouse/.test(t.originalEvent.type)?(this.menu.blur(),this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)})):(s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
    ").text(i))},100)))},menuselect:function(t,e){var e=e.item.data("ui-autocomplete-item"),i=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.trigger("focus"),this.previous=i),!1!==this._trigger("select",t,{item:e})&&this._value(e.value),this.term=this._value(),this.close(t),this.selectedItem=e}}),this.liveRegion=x("
    ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=(t=(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))&&t[0]?t:this.element.closest(".ui-front, dialog")).length?t:this.document[0].body},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
    ").text(e.label)).appendTo(t)},_move:function(t,e){this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur()):this.menu[t](e):this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}}),x.ui.autocomplete}); \ No newline at end of file diff --git a/docs/Javadoc/apidocs/script-files/script.js b/docs/Javadoc/apidocs/script-files/script.js new file mode 100644 index 00000000..02b12074 --- /dev/null +++ b/docs/Javadoc/apidocs/script-files/script.js @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + */ + +var moduleSearchIndex; +var packageSearchIndex; +var typeSearchIndex; +var memberSearchIndex; +var tagSearchIndex; + +var oddRowColor = "odd-row-color"; +var evenRowColor = "even-row-color"; +var sortAsc = "sort-asc"; +var sortDesc = "sort-desc"; +var tableTab = "table-tab"; +var activeTableTab = "active-table-tab"; + +const linkIcon = "Link icon"; +const linkToSection = "Link to this section"; + +if (typeof hljs !== "undefined") { + try { + hljs.highlightAll(); + } catch (err) { + console.error(err) + } +} + +function loadScripts(doc, tag) { + createElem(doc, tag, 'script-files/search.js'); + + createElem(doc, tag, 'module-search-index.js'); + createElem(doc, tag, 'package-search-index.js'); + createElem(doc, tag, 'type-search-index.js'); + createElem(doc, tag, 'member-search-index.js'); + createElem(doc, tag, 'tag-search-index.js'); +} + +function createElem(doc, tag, path) { + var script = doc.createElement(tag); + var scriptElement = doc.getElementsByTagName(tag)[0]; + script.src = pathtoroot + path; + scriptElement.parentNode.insertBefore(script, scriptElement); +} + +// Helper for making content containing release names comparable lexicographically +function makeComparable(s) { + return s.toLowerCase().replace(/(\d+)/g, + function(n, m) { + return ("000" + m).slice(-4); + }); +} + +// Switches between two styles depending on a condition +function toggleStyle(classList, condition, trueStyle, falseStyle) { + if (condition) { + classList.remove(falseStyle); + classList.add(trueStyle); + } else { + classList.remove(trueStyle); + classList.add(falseStyle); + } +} + +// Sorts the rows in a table lexicographically by the content of a specific column +function sortTable(header, columnIndex, columns) { + var container = header.parentElement; + var descending = header.classList.contains(sortAsc); + container.querySelectorAll("div.table-header").forEach( + function(header) { + header.classList.remove(sortAsc); + header.classList.remove(sortDesc); + } + ) + var cells = container.children; + var rows = []; + for (var i = columns; i < cells.length; i += columns) { + rows.push(Array.prototype.slice.call(cells, i, i + columns)); + } + var comparator = function(a, b) { + var ka = makeComparable(a[columnIndex].textContent); + var kb = makeComparable(b[columnIndex].textContent); + if (ka < kb) + return descending ? 1 : -1; + if (ka > kb) + return descending ? -1 : 1; + return 0; + }; + var sorted = rows.sort(comparator); + var visible = 0; + sorted.forEach(function(row) { + if (row[0].style.display !== 'none') { + var isEvenRow = visible++ % 2 === 0; + } + row.forEach(function(cell) { + toggleStyle(cell.classList, isEvenRow, evenRowColor, oddRowColor); + container.appendChild(cell); + }) + }); + toggleStyle(header.classList, descending, sortDesc, sortAsc); +} + +// Toggles the visibility of a table category in all tables in a page +function toggleGlobal(checkbox, selected, columns) { + const display = checkbox.checked ? '' : 'none'; + const selectOther = selected === "other"; + const selectAll = selected === "all"; + if (selectAll) { + document.querySelectorAll('.checkboxes input[type="checkbox"]').forEach(c => { + c.checked = checkbox.checked; + }); + } + document.querySelectorAll("div.table-tabs").forEach(t => { + const id = t.parentElement.getAttribute("id"); + const selectedClass = id + "-tab" + (selectOther ? "" : selected); + var visible = 0; + t.parentElement.querySelectorAll('div.' + id) + .forEach(function(elem) { + if (selectAll + || (!selectOther && elem.classList.contains(selectedClass)) + || (selectOther && elem.className.indexOf(selectedClass) < 0)) { + elem.style.display = display; + } + if (elem.style.display === '') { + var isEvenRow = visible++ % (columns * 2) < columns; + toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); + } + }); + var displaySection = visible === 0 ? 'none' : ''; + t.parentElement.style.display = displaySection; + document.querySelector("li#contents-" + id).style.display = displaySection; + }) +} + +// Shows the elements of a table belonging to a specific category +function show(tableId, selected, columns) { + if (tableId !== selected) { + document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') + .forEach(function(elem) { + elem.style.display = 'none'; + }); + } + document.querySelectorAll('div.' + selected) + .forEach(function(elem, index) { + elem.style.display = ''; + var isEvenRow = index % (columns * 2) < columns; + toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); + }); + updateTabs(tableId, selected); +} + +function updateTabs(tableId, selected) { + document.getElementById(tableId + '.tabpanel') + .setAttribute('aria-labelledby', selected); + document.querySelectorAll('button[id^="' + tableId + '"]') + .forEach(function(tab, index) { + if (selected === tab.id || (tableId === selected && index === 0)) { + tab.className = activeTableTab; + tab.setAttribute('aria-selected', true); + tab.setAttribute('tabindex',0); + } else { + tab.className = tableTab; + tab.setAttribute('aria-selected', false); + tab.setAttribute('tabindex',-1); + } + }); +} + +function switchTab(e) { + var selected = document.querySelector('[aria-selected=true]'); + if (selected) { + if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { + // left or up arrow key pressed: move focus to previous tab + selected.previousSibling.click(); + selected.previousSibling.focus(); + e.preventDefault(); + } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { + // right or down arrow key pressed: move focus to next tab + selected.nextSibling.click(); + selected.nextSibling.focus(); + e.preventDefault(); + } + } +} + +var updateSearchResults = function() {}; + +function indexFilesLoaded() { + return moduleSearchIndex + && packageSearchIndex + && typeSearchIndex + && memberSearchIndex + && tagSearchIndex; +} +// Copy the contents of the local snippet to the clipboard +function copySnippet(button) { + copyToClipboard(button.nextElementSibling.innerText); + switchCopyLabel(button, button.firstElementChild); +} +function copyToClipboard(content) { + var textarea = document.createElement("textarea"); + textarea.style.height = 0; + document.body.appendChild(textarea); + textarea.value = content; + textarea.select(); + document.execCommand("copy"); + document.body.removeChild(textarea); +} +function resetInput(input, event, blur) { + if (input.value) { + input.value = ""; + input.dispatchEvent(new InputEvent("input")); + } else if (blur) { + input.blur(); + } + event.preventDefault(); +} +function isInput(elem) { + return elem instanceof HTMLInputElement && elem.type === "text"; +} +function switchCopyLabel(button, span) { + var copied = span.getAttribute("data-copied"); + button.classList.add("visible"); + var initialLabel = span.innerHTML; + span.innerHTML = copied; + setTimeout(function() { + button.classList.remove("visible"); + setTimeout(function() { + if (initialLabel !== copied) { + span.innerHTML = initialLabel; + } + }, 100); + }, 1900); +} +function makeFilterWidget(sidebar, updateToc) { + if (!sidebar) { + return null; + } + const filterInput = sidebar.querySelector("input.filter-input"); + const resetInput = sidebar.querySelector("input.reset-filter"); + sidebar.addEventListener("keydown", e => { + if (e.ctrlKey || e.altKey || e.metaKey) { + return; + } + if (e.key === "ArrowUp" || e.key === "ArrowDown") { + handleTocFocus(e); + } else if (filterInput && e.target !== filterInput) { + if (e.key === "Enter" && isTocLink(sidebar, e.target)) { + filterInput.value = ""; + filterInput.dispatchEvent(new InputEvent("input")); + } else if (e.key.length === 1 || e.key === "Backspace") { + filterInput.focus(); + } + } + }); + if (filterInput) { + filterInput.removeAttribute("disabled"); + filterInput.setAttribute("autocapitalize", "off"); + filterInput.value = ""; + filterInput.addEventListener("input", function(e) { + resetInput.style.visibility = filterInput.value ? "visible" : "hidden"; + const pattern = filterInput.value ? filterInput.value.trim() + .replace(/[\[\]{}()*+?.\\^$|]/g, '\\$&') + .replace(/\s+/g, ".*") : ""; + const filter = new RegExp(pattern, "i"); + sidebar.querySelectorAll("ol.toc-list li").forEach((li) => { + if (filter.test(li.innerText)) { + // li.removeAttribute("style"); + const selfMatch = filter.test(li.firstElementChild.innerText); + li.style.display = "block"; + li.firstElementChild.style.opacity = selfMatch ? "100%" : "70%"; + li.firstElementChild.tabIndex = selfMatch ? 0 : -1; + } else { + li.style.display = "none"; + } + }); + updateToc(); + }); + } + if (resetInput) { + resetInput.removeAttribute("disabled"); + resetInput.addEventListener("click", (e) => { + filterInput.value = ""; + filterInput.focus(); + filterInput.dispatchEvent(new InputEvent("input")); + }); + } + function handleTocFocus(event) { + let links = Array.from(sidebar.querySelectorAll("ol > li > a")) + .filter(link => link.offsetParent && link.tabIndex === 0); + let current = links.indexOf(document.activeElement); + if (event.key === "ArrowUp") { + if (current > 0) { + links[current - 1].focus({focusVisible: true}); + } else if (filterInput) { + filterInput.focus(); + } + } else if (event.key === "ArrowDown" && current < links.length - 1) { + links[current + 1].focus({focusVisible: true}); + } + event.preventDefault(); + } + function isTocLink(sidebar, elem) { + let links = Array.from(sidebar.querySelectorAll("ol > li > a")) + .filter(link => link.offsetParent && link.tabIndex === 0); + return links.indexOf(elem) > -1; + } + return sidebar; +} + +function setTopMargin() { + // Dynamically set scroll margin to accomodate for draft header + var headerHeight = Math.ceil(document.querySelector("header").offsetHeight); + document.querySelector(":root") + .style.setProperty("--nav-height", headerHeight + "px"); +} +document.addEventListener("readystatechange", (e) => { + if (document.readyState === "interactive") { + setTopMargin(); + } + if (sessionStorage.getItem("sidebar") === "hidden") { + const sidebar = document.querySelector(".main-grid nav.toc"); + if (sidebar) sidebar.classList.add("hide-sidebar"); + } +}); +document.addEventListener("DOMContentLoaded", function(e) { + setTopMargin(); + // Make sure current element is visible in breadcrumb navigation on small displays + const subnav = document.querySelector("ol.sub-nav-list"); + if (subnav && subnav.lastElementChild) { + subnav.lastElementChild.scrollIntoView({ behavior: "instant", inline: "start", block: "nearest" }); + } + const keymap = new Map(); + const searchInput = document.getElementById("search-input") + || document.getElementById("page-search-input"); + if (searchInput) { + searchInput.addEventListener("focus", collapse); + keymap.set("/", searchInput); + } + const filterInput = document.querySelector("input.filter-input"); + if (filterInput) { + keymap.set(".", filterInput); + } + // Clone TOC sidebar to header for mobile navigation + const navbar = document.querySelector("div#navbar-top"); + const sidebar = document.querySelector(".main-grid nav.toc"); + const main = document.querySelector(".main-grid main"); + const mainnav = navbar.querySelector("ul.nav-list"); + const toggleButton = document.querySelector("button#navbar-toggle-button"); + const tocMenu = sidebar ? sidebar.cloneNode(true) : null; + makeFilterWidget(sidebar, updateToc); + if (tocMenu) { + navbar.appendChild(tocMenu); + makeFilterWidget(tocMenu, updateToc); + var menuInput = tocMenu.querySelector("input.filter-input"); + } + document.addEventListener("keydown", (e) => { + if (e.ctrlKey || e.altKey || e.metaKey) { + return; + } + if (!isInput(e.target) && keymap.has(e.key)) { + var elem = keymap.get(e.key); + if (elem === filterInput && !elem.offsetParent) { + elem = getVisibleFilterInput(true); + } + elem.focus(); + elem.select(); + e.preventDefault(); + } else if (e.key === "Escape") { + if (expanded) { + collapse(); + e.preventDefault(); + } else if (e.target.id === "page-search-input") { + resetInput(e.target, e, false); + } else if (isInput(e.target)) { + resetInput(e.target, e, true); + } else { + var filter = getVisibleFilterInput(false); + if (filter && filter.value) { + resetInput(filterInput, e, true); + } + } + } + }); + var expanded = false; + var windowWidth; + var bodyHeight; + function collapse() { + if (expanded) { + mainnav.removeAttribute("style"); + if (tocMenu) { + tocMenu.removeAttribute("style"); + if (filterInput) { + keymap.set(".", filterInput); + } + } + toggleButton.classList.remove("expanded") + toggleButton.setAttribute("aria-expanded", "false"); + expanded = false; + } + } + function expand() { + expanded = true; + mainnav.style.display = "block"; + mainnav.style.removeProperty("height"); + var maxHeight = window.innerHeight - subnav.offsetTop + 4; + var expandedHeight = Math.min(maxHeight, mainnav.scrollHeight + 10); + if (tocMenu) { + tocMenu.style.display = "flex"; + expandedHeight = Math.min(maxHeight, + Math.max(expandedHeight, tocMenu.querySelector("div.toc-header").offsetHeight + + tocMenu.querySelector("ol.toc-list").scrollHeight + 10)); + tocMenu.style.height = expandedHeight + "px"; + if (menuInput) { + keymap.set(".", menuInput); + } + } + mainnav.style.height = expandedHeight + "px"; + toggleButton.classList.add("expanded"); + toggleButton.setAttribute("aria-expanded", "true"); + windowWidth = window.innerWidth; + } + function updateToc() { + if (expanded) { + expand(); + } else { + prevHash = null; + handleScroll(); + } + } + function getVisibleFilterInput(show) { + if (sidebar && sidebar.offsetParent) { + if (show) { + showSidebar(); + } + return filterInput; + } else { + if (show) { + expand(); + } + return menuInput; + } + } + toggleButton.addEventListener("click", (e) => { + if (expanded) { + collapse(); + } else { + expand(); + } + }); + if (tocMenu) { + tocMenu.querySelectorAll("a").forEach((link) => { + link.addEventListener("click", collapse); + }); + } + document.querySelector("main").addEventListener("click", collapse); + document.querySelectorAll("h1, h2, h3, h4, h5, h6") + .forEach((hdr, idx) => { + // Create anchor links for headers with an associated id attribute + var id = hdr.parentElement.getAttribute("id") || hdr.getAttribute("id") + || (hdr.querySelector("a") && hdr.querySelector("a").getAttribute("id")); + if (id) { + var template = document.createElement('template'); + template.innerHTML =" " + linkIcon +""; + hdr.append(...template.content.childNodes); + } + }); + var sections; + var scrollTimeout; + var prevHash; + function initSectionData() { + bodyHeight = document.body.offsetHeight; + sections = [{ id: "", top: 0 }].concat(Array.from(main.querySelectorAll( + "section[id], h2[id], h2 a[id], h3[id], h3 a[id], div[id]")) + .filter((e) => { + return sidebar.querySelector("a[href=\"#" + encodeURI(e.getAttribute("id")) + "\"]") !== null + }).map((e) => { + return { + id: e.getAttribute("id"), + top: e.offsetTop + }; + })); + } + function setScrollTimeout() { + if (scrollTimeout) { + clearTimeout(scrollTimeout); + } + scrollTimeout = setTimeout(() => { + scrollTimeout = null; + }, 100); + } + function handleScroll() { + if (!sidebar || !sidebar.offsetParent || sidebar.classList.contains("hide-sidebar")) { + return; + } + if (scrollTimeout) { + setScrollTimeout(); + return; + } + var scrollTop = document.documentElement.scrollTop; + var scrollHeight = document.documentElement.scrollHeight; + var currHash = null; + for (var i = 0; i < sections.length; i++) { + var top = sections[i].top; + var bottom = sections[i + 1] ? sections[i + 1].top : scrollHeight; + if (top + ((bottom - top) / 2) > scrollTop || bottom > scrollTop + (window.innerHeight / 3)) { + currHash = "#" + encodeURI(sections[i].id); + break; + } + } + if (currHash !== prevHash) { + setSelected(currHash); + } + } + function setSelected(hash) { + var prev = sidebar.querySelector("a.current-selection"); + if (prev) + prev.classList.remove("current-selection"); + prevHash = hash; + if (hash) { + var curr = sidebar.querySelector("ol.toc-list a[href=\"" + hash + "\"]"); + if (curr) { + curr.classList.add("current-selection"); + curr.scrollIntoView({ behavior: "instant", block: "nearest" }); + } + } + } + function hideSidebar() { + sidebar.classList.add("hide-sidebar"); + sessionStorage.setItem("sidebar", "hidden"); + } + function showSidebar() { + sidebar.classList.remove("hide-sidebar"); + sessionStorage.removeItem("sidebar"); + initSectionData(); + handleScroll(); + } + if (sidebar) { + initSectionData(); + document.querySelectorAll("a[href^='#']").forEach((link) => { + link.addEventListener("click", (e) => { + link.blur(); + setScrollTimeout(); + setSelected(link.getAttribute("href")); + }) + }); + sidebar.querySelector("button.hide-sidebar").addEventListener("click", hideSidebar); + sidebar.querySelector("button.show-sidebar").addEventListener("click", showSidebar); + window.addEventListener("hashchange", (e) => { + setScrollTimeout(); + const hash = e.newURL.indexOf("#"); + if (hash > -1) { + setSelected(e.newURL.substring(hash)); + } + }); + if (document.location.hash) { + setScrollTimeout(); + setSelected(document.location.hash); + } else { + handleScroll(); + } + window.addEventListener("scroll", handleScroll); + } + // Resize handler + new ResizeObserver((entries) => { + if (expanded) { + if (windowWidth !== window.innerWidth) { + collapse(); + } else { + expand(); + } + } + if (sections && document.body.offsetHeight !== bodyHeight) { + initSectionData(); + prevHash = null; + handleScroll(); + } + setTopMargin(); + }).observe(document.body); +}); diff --git a/docs/Javadoc/apidocs/script-files/search-page.js b/docs/Javadoc/apidocs/script-files/search-page.js new file mode 100644 index 00000000..ec0d815e --- /dev/null +++ b/docs/Javadoc/apidocs/script-files/search-page.js @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + */ + +"use strict"; +$(function() { + var copy = $("#page-search-copy"); + var expand = $("#page-search-expand"); + var searchLink = $("span#page-search-link"); + var redirect = $("input#search-redirect"); + function setSearchUrlTemplate() { + var href = document.location.href.split(/[#?]/)[0]; + href += "?q=" + "%s"; + if (redirect.is(":checked")) { + href += "&r=1"; + } + searchLink.html(href); + copy[0].onmouseenter(); + } + function copyLink(e) { + copyToClipboard(this.previousSibling.innerText); + switchCopyLabel(this, this.lastElementChild); + } + copy.on("click", copyLink); + copy[0].onmouseenter = function() {}; + redirect.on("click", setSearchUrlTemplate); + setSearchUrlTemplate(); + copy.prop("disabled", false); + redirect.prop("disabled", false); + expand.on("click", function (e) { + var searchInfo = $("div.page-search-info"); + if(this.parentElement.hasAttribute("open")) { + searchInfo.attr("style", " display:none;"); + } else { + searchInfo.attr("style", "display:block;"); + } + }); +}); +$(window).on("load", function() { + var input = $("#page-search-input"); + var reset = $("#page-search-reset"); + var modules = $("#search-modules"); + var notify = $("#page-search-notify"); + var resultSection = $("div#result-section"); + var resultContainer = $("div#result-container"); + var selectedLink; + var searchTerm = ""; + var activeTab = ""; + var fixedTab = false; + var visibleTabs = []; + var feelingLucky = false; + const MIN_TABBED_RESULTS = 10; + function renderResults(result) { + if (!result.length) { + notify.html(messages.noResult); + } else if (result.length === 1) { + notify.html(messages.oneResult); + } else { + notify.html(messages.manyResults.replace("{0}", result.length)); + } + resultContainer.empty(); + var r = { + "types": [], + "members": [], + "packages": [], + "modules": [], + "searchTags": [] + }; + for (var i in result) { + var item = result[i]; + var arr = r[item.category]; + arr.push(item); + } + if (!activeTab || r[activeTab].length === 0) { + activeTab = Object.keys(r).find(category => r[category].length > 0); + } + if (feelingLucky && activeTab) { + notify.html(messages.redirecting) + var firstItem = r[activeTab][0]; + window.location = getURL(firstItem.indexItem, firstItem.category); + return; + } + if (searchTerm.endsWith(".") && result.length > MIN_TABBED_RESULTS) { + if (activeTab === "types" && r["members"].length > r["types"].length) { + activeTab = "members"; + } else if (activeTab === "packages" && r["types"].length > r["packages"].length) { + activeTab = "types"; + } + } + var categoryCount = Object.keys(r).reduce(function(prev, curr) { + return prev + (r[curr].length > 0 ? 1 : 0); + }, 0); + visibleTabs = []; + var tabContainer = $("
    ").appendTo(resultContainer); + for (var key in r) { + var id = "#result-tab-" + key.replace("searchTags", "search_tags"); + if (r[key].length) { + var count = r[key].length >= 1000 ? "999+" : r[key].length; + if (result.length > MIN_TABBED_RESULTS && categoryCount > 1) { + let button = $("
    + + +
    +
    + + + + +
    +
    +

    Search

    +
    +
    +Additional resources +
    +
    +
    +

    The help page provides an introduction to the scope and syntax of JavaDoc search.

    +

    Use the + +/ + + keys to move between search results and the + +/ + + keys to switch between result tabs.

    +

    The URL template below may be useful to configure this page as a search engine or bookmarklet in browsers that support this feature.

    +link +

    +
    +

    Loading search index...

    + +
    +
    + +
    +
    +
    + + diff --git a/docs/Javadoc/apidocs/tag-search-index.js b/docs/Javadoc/apidocs/tag-search-index.js new file mode 100644 index 00000000..0367dae6 --- /dev/null +++ b/docs/Javadoc/apidocs/tag-search-index.js @@ -0,0 +1 @@ +tagSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/docs/Javadoc/apidocs/type-search-index.js b/docs/Javadoc/apidocs/type-search-index.js new file mode 100644 index 00000000..266a3568 --- /dev/null +++ b/docs/Javadoc/apidocs/type-search-index.js @@ -0,0 +1 @@ +typeSearchIndex = [{"l":"All Classes and Interfaces","u":"allclasses-index.html","k":"18"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","l":"APICharityData"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","l":"APICharityScraper"},{"p":"ntnu.systemutvikling.team6.service","l":"APIToDatabaseService"},{"p":"ntnu.systemutvikling.team6.service","l":"AuthenticationService"},{"p":"ntnu.systemutvikling.team6.controller","l":"AvailableOrganizationController"},{"p":"ntnu.systemutvikling.team6.controller.components","l":"BaseController"},{"p":"ntnu.systemutvikling.team6.database.Readers","l":"CategorySelect"},{"p":"ntnu.systemutvikling.team6.models","l":"Charity"},{"p":"ntnu.systemutvikling.team6.controller","l":"CharityPageController"},{"p":"ntnu.systemutvikling.team6.models.registry","l":"CharityRegistry"},{"p":"ntnu.systemutvikling.team6.database.Readers","l":"CharitySelect"},{"p":"ntnu.systemutvikling.team6.service","l":"CharityService"},{"p":"ntnu.systemutvikling.team6.database","l":"DatabaseConnection"},{"p":"ntnu.systemutvikling.team6.database","l":"DatabaseSetup"},{"p":"ntnu.systemutvikling.team6.models","l":"Donation"},{"p":"ntnu.systemutvikling.team6.database.DAO","l":"DonationDAO"},{"p":"ntnu.systemutvikling.team6.controller","l":"DonationPageController"},{"p":"ntnu.systemutvikling.team6.models.registry","l":"DonationRegistry"},{"p":"ntnu.systemutvikling.team6.database.Readers","l":"DonationSelect"},{"p":"ntnu.systemutvikling.team6.service","l":"DonationService"},{"p":"ntnu.systemutvikling.team6.models","l":"Feedback"},{"p":"ntnu.systemutvikling.team6.service","l":"FeedbackService"},{"p":"ntnu.systemutvikling.team6.controller","l":"FrontpageController"},{"p":"ntnu.systemutvikling.team6.scraper","l":"FullCharityScrape"},{"p":"ntnu.systemutvikling.team6","l":"HmHApplication"},{"p":"ntnu.systemutvikling.team6.models.user","l":"Inbox"},{"p":"ntnu.systemutvikling.team6.models.user","l":"Language","k":"9"},{"p":"ntnu.systemutvikling.team6.controller.components","l":"LoaderScene"},{"p":"ntnu.systemutvikling.team6.scraper","l":"LogoDownloader"},{"p":"ntnu.systemutvikling.team6","l":"Main"},{"p":"ntnu.systemutvikling.team6.models.user","l":"Message"},{"p":"ntnu.systemutvikling.team6.controller.components","l":"NavbarFooterController","k":"10"},{"p":"ntnu.systemutvikling.team6.controller.components","l":"OrganizationCardController"},{"p":"ntnu.systemutvikling.team6.security","l":"PasswordHasher"},{"p":"ntnu.systemutvikling.team6.models.user","l":"Role","k":"9"},{"p":"ntnu.systemutvikling.team6.models.user","l":"Settings"},{"p":"ntnu.systemutvikling.team6.scraper.scraperComponents","l":"URLCharityScraper"},{"p":"ntnu.systemutvikling.team6.models.user","l":"User"},{"p":"ntnu.systemutvikling.team6.database.DAO","l":"UserDAO"},{"p":"ntnu.systemutvikling.team6.models.registry","l":"UserRegistry"},{"p":"ntnu.systemutvikling.team6.database.Readers","l":"UserSelect"}];updateSearchResults(); \ No newline at end of file diff --git a/docs/MainReport/Appendix 1.0 PDF.pdf b/docs/MainReport/Appendix 1.0 PDF.pdf new file mode 100644 index 00000000..a03d1788 Binary files /dev/null and b/docs/MainReport/Appendix 1.0 PDF.pdf differ diff --git a/docs/MainReport/Appendix 1.0.docx b/docs/MainReport/Appendix 1.0.docx new file mode 100644 index 00000000..205f9b5a Binary files /dev/null and b/docs/MainReport/Appendix 1.0.docx differ diff --git a/docs/MainReport/Main Report 1.1 PDF.pdf b/docs/MainReport/Main Report 1.1 PDF.pdf new file mode 100644 index 00000000..e02bf255 Binary files /dev/null and b/docs/MainReport/Main Report 1.1 PDF.pdf differ diff --git a/docs/MainReport/Main Report 1.1.docx b/docs/MainReport/Main Report 1.1.docx new file mode 100644 index 00000000..e53e0dc3 Binary files /dev/null and b/docs/MainReport/Main Report 1.1.docx differ diff --git a/docs/SqlDatabase/ER-Diagram Final.png b/docs/SqlDatabase/ER-Diagram Final.png new file mode 100644 index 00000000..3a556cfe Binary files /dev/null and b/docs/SqlDatabase/ER-Diagram Final.png differ diff --git a/docs/ER-Diagram v1.png b/docs/SqlDatabase/ER-Diagram v1.png similarity index 100% rename from docs/ER-Diagram v1.png rename to docs/SqlDatabase/ER-Diagram v1.png diff --git a/docs/ER-Diagram v2.png b/docs/SqlDatabase/ER-Diagram v2.png similarity index 100% rename from docs/ER-Diagram v2.png rename to docs/SqlDatabase/ER-Diagram v2.png diff --git a/docs/SqlDatabase/ER-Diagram v3.png b/docs/SqlDatabase/ER-Diagram v3.png new file mode 100644 index 00000000..af63917c Binary files /dev/null and b/docs/SqlDatabase/ER-Diagram v3.png differ diff --git a/docs/SqlDatabase/ER-Diagram v4.png b/docs/SqlDatabase/ER-Diagram v4.png new file mode 100644 index 00000000..bffbaf8a Binary files /dev/null and b/docs/SqlDatabase/ER-Diagram v4.png differ diff --git a/docs/SqlDatabase/ER-Diagram v5.png b/docs/SqlDatabase/ER-Diagram v5.png new file mode 100644 index 00000000..df229943 Binary files /dev/null and b/docs/SqlDatabase/ER-Diagram v5.png differ diff --git a/docs/SqlDatabase/ER-DiagramFile.mwb b/docs/SqlDatabase/ER-DiagramFile.mwb new file mode 100644 index 00000000..7535f5b2 Binary files /dev/null and b/docs/SqlDatabase/ER-DiagramFile.mwb differ diff --git a/docs/SqlDatabase/ER-DiagramFile.mwb.bak b/docs/SqlDatabase/ER-DiagramFile.mwb.bak new file mode 100644 index 00000000..5105a8b1 Binary files /dev/null and b/docs/SqlDatabase/ER-DiagramFile.mwb.bak differ diff --git a/docs/SqlDatabase/Sql_script_v1.1.sql b/docs/SqlDatabase/Sql_script_v1.1.sql new file mode 100644 index 00000000..63104556 --- /dev/null +++ b/docs/SqlDatabase/Sql_script_v1.1.sql @@ -0,0 +1,203 @@ +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `apbaluna` DEFAULT CHARACTER SET utf8 ; +USE `apbaluna` ; + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charities` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charities` ( + `UUID_charities` CHAR(36) NOT NULL, + `org_number` VARCHAR(255) NOT NULL, + `charity_name` VARCHAR(255) NOT NULL, + `charity_description` VARCHAR(255) NOT NULL, + `charity_link` VARCHAR(255) NOT NULL, + `pre_approved` TINYINT NOT NULL, + `status` VARCHAR(255) NOT NULL, + PRIMARY KEY (`UUID_charities`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`User` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`User` ( + `UUID_User` CHAR(36) NOT NULL, + `user_name` VARCHAR(255) NOT NULL, + `user_email` VARCHAR(255) NOT NULL, + `role` VARCHAR(45) NOT NULL, + PRIMARY KEY (`UUID_User`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Donations` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Donations` ( + `UUID_Donations` CHAR(36) NOT NULL, + `amount` DECIMAL NOT NULL, + `date` DATE NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_Donations`), + INDEX `fk_Donations_Charities_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Donations_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Donations_Charities` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Donations_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Settings` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Settings` ( + `User_UUID_User` CHAR(36) NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `language` VARCHAR(45) NOT NULL, + `lightmode` TINYINT NOT NULL, + PRIMARY KEY (`User_UUID_User`), + INDEX `fk_Settings_User1_idx` (`User_UUID_User` ASC) VISIBLE, + CONSTRAINT `fk_Settings_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Messages` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Messages` ( + `UUID_message` CHAR(36) NOT NULL, + `message_title` VARCHAR(255) NOT NULL, + `message_content` VARCHAR(255) NOT NULL, + `message_date` DATE NOT NULL, + `sender_user_id` CHAR(36) NULL, + `sender_charity_id` CHAR(36) NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_message`), + INDEX `fk_Messages_User1_idx` (`sender_user_id` ASC) VISIBLE, + INDEX `fk_Messages_Charities1_idx` (`sender_charity_id` ASC) VISIBLE, + INDEX `fk_Messages_User2_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Messages_User1` + FOREIGN KEY (`sender_user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_Charities1` + FOREIGN KEY (`sender_charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_User2` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Feedback` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Feedback` ( + `UUID_feedback` CHAR(36) NOT NULL, + `feedback_comment` VARCHAR(255) NOT NULL, + `feedback_date` DATE NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_feedback`), + INDEX `fk_Feedback_Charities1_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Feedback_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Feedback_Charities1` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Feedback_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Categories` ( + `category_id` INT NOT NULL AUTO_INCREMENT, + `category` VARCHAR(255) NOT NULL, + PRIMARY KEY (`category_id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charity_Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charity_Categories` ( + `Categories_category_id` INT NOT NULL, + `Charities_UUID_charities` CHAR(36) NOT NULL, + PRIMARY KEY (`Categories_category_id`, `Charities_UUID_charities`), + INDEX `fk_Categories_has_Charities_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + INDEX `fk_Categories_has_Charities_Categories1_idx` (`Categories_category_id` ASC) VISIBLE, + CONSTRAINT `fk_Categories_has_Charities_Categories1` + FOREIGN KEY (`Categories_category_id`) + REFERENCES `apbaluna`.`Categories` (`category_id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Categories_has_Charities_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`CharityUsers` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`CharityUsers` ( + `Charities_UUID_charities` CHAR(36) NOT NULL, + `User_UUID_User` CHAR(36) NOT NULL, + PRIMARY KEY (`Charities_UUID_charities`, `User_UUID_User`), + INDEX `fk_Charities_has_User_User1_idx` (`User_UUID_User` ASC) VISIBLE, + INDEX `fk_Charities_has_User_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + CONSTRAINT `fk_Charities_has_User_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Charities_has_User_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + +USE `apbaluna`; + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/docs/SqlDatabase/Sql_script_v1.2.sql b/docs/SqlDatabase/Sql_script_v1.2.sql new file mode 100644 index 00000000..4acb7589 --- /dev/null +++ b/docs/SqlDatabase/Sql_script_v1.2.sql @@ -0,0 +1,203 @@ +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `apbaluna` DEFAULT CHARACTER SET utf8 ; +USE `apbaluna` ; + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charities` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charities` ( + `UUID_charities` CHAR(36) NOT NULL, + `org_number` VARCHAR(255) NOT NULL, + `charity_name` VARCHAR(255) NOT NULL, + `charity_description` VARCHAR(255) NOT NULL, + `charity_link` VARCHAR(255) NOT NULL, + `pre_approved` TINYINT NOT NULL, + `status` VARCHAR(255) NOT NULL, + PRIMARY KEY (`UUID_charities`), + UNIQUE INDEX `org_number_UNIQUE` (`org_number` ASC) VISIBLE) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`User` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`User` ( + `UUID_User` CHAR(36) NOT NULL, + `user_name` VARCHAR(255) NOT NULL, + `user_email` VARCHAR(255) NOT NULL, + `role` VARCHAR(45) NOT NULL, + PRIMARY KEY (`UUID_User`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Donations` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Donations` ( + `UUID_Donations` CHAR(36) NOT NULL, + `amount` DECIMAL NOT NULL, + `date` DATE NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_Donations`), + INDEX `fk_Donations_Charities_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Donations_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Donations_Charities` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Donations_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Settings` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Settings` ( + `User_UUID_User` CHAR(36) NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `language` VARCHAR(45) NOT NULL, + `lightmode` TINYINT NOT NULL, + PRIMARY KEY (`User_UUID_User`), + INDEX `fk_Settings_User1_idx` (`User_UUID_User` ASC) VISIBLE, + CONSTRAINT `fk_Settings_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Messages` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Messages` ( + `UUID_message` CHAR(36) NOT NULL, + `message_title` VARCHAR(255) NOT NULL, + `message_content` VARCHAR(255) NOT NULL, + `message_date` DATE NOT NULL, + `sender_user_id` CHAR(36) NULL, + `sender_charity_id` CHAR(36) NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_message`), + INDEX `fk_Messages_User1_idx` (`sender_user_id` ASC) VISIBLE, + INDEX `fk_Messages_Charities1_idx` (`sender_charity_id` ASC) VISIBLE, + INDEX `fk_Messages_User2_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Messages_User1` + FOREIGN KEY (`sender_user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_Charities1` + FOREIGN KEY (`sender_charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_User2` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Feedback` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Feedback` ( + `UUID_feedback` CHAR(36) NOT NULL, + `feedback_comment` VARCHAR(255) NOT NULL, + `feedback_date` DATE NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_feedback`), + INDEX `fk_Feedback_Charities1_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Feedback_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Feedback_Charities1` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Feedback_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Categories` ( + `category_id` INT NOT NULL AUTO_INCREMENT, + `category` VARCHAR(255) NOT NULL, + PRIMARY KEY (`category_id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charity_Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charity_Categories` ( + `Categories_category_id` INT NOT NULL, + `Charities_UUID_charities` CHAR(36) NOT NULL, + PRIMARY KEY (`Categories_category_id`, `Charities_UUID_charities`), + INDEX `fk_Categories_has_Charities_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + INDEX `fk_Categories_has_Charities_Categories1_idx` (`Categories_category_id` ASC) VISIBLE, + CONSTRAINT `fk_Categories_has_Charities_Categories1` + FOREIGN KEY (`Categories_category_id`) + REFERENCES `apbaluna`.`Categories` (`category_id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Categories_has_Charities_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`CharityUsers` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`CharityUsers` ( + `Charities_UUID_charities` CHAR(36) NOT NULL, + `User_UUID_User` CHAR(36) NOT NULL, + PRIMARY KEY (`Charities_UUID_charities`, `User_UUID_User`), + INDEX `fk_Charities_has_User_User1_idx` (`User_UUID_User` ASC) VISIBLE, + INDEX `fk_Charities_has_User_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + CONSTRAINT `fk_Charities_has_User_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Charities_has_User_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/docs/SqlDatabase/Sql_scriptv1.0.sql b/docs/SqlDatabase/Sql_scriptv1.0.sql new file mode 100644 index 00000000..529aac8f --- /dev/null +++ b/docs/SqlDatabase/Sql_scriptv1.0.sql @@ -0,0 +1,213 @@ +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- + +-- ----------------------------------------------------- +-- Schema apbaluna +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `apbaluna` DEFAULT CHARACTER SET utf8 ; +USE `apbaluna` ; + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charities` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charities` ( + `UUID_charities` CHAR(36) NOT NULL, + `org_number` VARCHAR(255) NOT NULL, + `charity_name` VARCHAR(255) NOT NULL, + `charity_description` VARCHAR(255) NOT NULL, + `charity_link` VARCHAR(255) NOT NULL, + `pre_approved` TINYINT NOT NULL, + `status` VARCHAR(255) NOT NULL, + PRIMARY KEY (`UUID_charities`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`User` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`User` ( + `UUID_User` CHAR(36) NOT NULL, + `user_name` VARCHAR(255) NOT NULL, + `user_email` VARCHAR(255) NOT NULL, + `role` VARCHAR(45) NOT NULL, + PRIMARY KEY (`UUID_User`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Donations` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Donations` ( + `UUID_Donations` CHAR(36) NOT NULL, + `amount` DECIMAL NOT NULL, + `date` DATE NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_Donations`), + INDEX `fk_Donations_Charities_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Donations_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Donations_Charities` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Donations_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Settings` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Settings` ( + `User_UUID_User` CHAR(36) NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `language` VARCHAR(45) NOT NULL, + `lightmode` TINYINT NOT NULL, + PRIMARY KEY (`User_UUID_User`), + INDEX `fk_Settings_User1_idx` (`User_UUID_User` ASC) VISIBLE, + CONSTRAINT `fk_Settings_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Messages` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Messages` ( + `UUID_message` CHAR(36) NOT NULL, + `message_title` VARCHAR(255) NOT NULL, + `message_content` VARCHAR(255) NOT NULL, + `message_date` DATE NOT NULL, + `sender_user_id` CHAR(36) NULL, + `sender_charity_id` CHAR(36) NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_message`), + INDEX `fk_Messages_User1_idx` (`sender_user_id` ASC) VISIBLE, + INDEX `fk_Messages_Charities1_idx` (`sender_charity_id` ASC) VISIBLE, + INDEX `fk_Messages_User2_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Messages_User1` + FOREIGN KEY (`sender_user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_Charities1` + FOREIGN KEY (`sender_charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_User2` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Feedback` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Feedback` ( + `UUID_feedback` CHAR(36) NOT NULL, + `feedback_comment` VARCHAR(255) NOT NULL, + `feedback_date` DATE NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_feedback`), + INDEX `fk_Feedback_Charities1_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Feedback_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Feedback_Charities1` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Feedback_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Categories` ( + `category_id` INT NOT NULL AUTO_INCREMENT, + `category` VARCHAR(255) NOT NULL, + PRIMARY KEY (`category_id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`Charity_Categories` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`Charity_Categories` ( + `Categories_category_id` INT NOT NULL, + `Charities_UUID_charities` CHAR(36) NOT NULL, + PRIMARY KEY (`Categories_category_id`, `Charities_UUID_charities`), + INDEX `fk_Categories_has_Charities_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + INDEX `fk_Categories_has_Charities_Categories1_idx` (`Categories_category_id` ASC) VISIBLE, + CONSTRAINT `fk_Categories_has_Charities_Categories1` + FOREIGN KEY (`Categories_category_id`) + REFERENCES `apbaluna`.`Categories` (`category_id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Categories_has_Charities_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `apbaluna`.`CharityUsers` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `apbaluna`.`CharityUsers` ( + `Charities_UUID_charities` CHAR(36) NOT NULL, + `User_UUID_User` CHAR(36) NOT NULL, + PRIMARY KEY (`Charities_UUID_charities`, `User_UUID_User`), + INDEX `fk_Charities_has_User_User1_idx` (`User_UUID_User` ASC) VISIBLE, + INDEX `fk_Charities_has_User_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + CONSTRAINT `fk_Charities_has_User_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Charities_has_User_User1` + FOREIGN KEY (`User_UUID_User`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + +USE `apbaluna`; + +DELIMITER $$ +USE `apbaluna`$$ +CREATE DEFINER = CURRENT_USER TRIGGER `apbaluna`.`User_AFTER_INSERT` AFTER INSERT ON `User` FOR EACH ROW +BEGIN + INSERT INTO apbaluna.Settings (User_UUID_User, isAnonymous, language, lightmode) VALUES (NEW.UUID_User, 0, 'English', 0); +END$$ + + +DELIMITER ; + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/etUUID(uuid); b/etUUID(uuid); new file mode 100644 index 00000000..74570f66 --- /dev/null +++ b/etUUID(uuid); @@ -0,0 +1,324 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + ESC-j * Forward one file line (or _N file lines). + ESC-k * Backward one file line (or _N file lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + ESC-b * Backward one window, but don't stop at beginning-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + Search is case-sensitive unless changed with -i or -I. + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r + Set screen colors. + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k _f_i_l_e ... --lesskey-file=_f_i_l_e + Use a compiled lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n ......... --line-numbers + Suppress line numbers in prompts and messages. + -N ......... --LINE-NUMBERS + Display line number at start of each line. + -o [_f_i_l_e] .. --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t _t_a_g .... --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces, tabs and carriage returns. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Set horizontal scroll amount (0 = one half screen width). + + --exit-follow-on-close + Exit F command on a pipe when writer closes pipe. + --file-size + Automatically determine the size of the input file. + --follow-name + The F command changes files if the input file is renamed. + --form-feed + Stop scrolling when a form feed character is reached. + --header=[_L[,_C[,_N]]] + Use _L lines (starting at line _N) and _C columns as headers. + --incsearch + Search file as each pattern character is typed in. + --intr=[_C] + Use _C instead of ^X to interrupt a read. + --lesskey-context=_t_e_x_t + Use lesskey source file contents. + --lesskey-src=_f_i_l_e + Use a lesskey source file. + --line-num-width=[_N] + Set the width of the -N line number field to _N characters. + --match-shift=[_N] + Show at least _N characters to the left of a search match. + --modelines=[_N] + Read _N lines from the input file and look for vim modelines. + --mouse + Enable mouse input. + --no-edit-warn + Don't warn when using v command on a file opened via LESSOPEN. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --no-number-headers + Don't give line numbers to header lines. + --no-paste + Ignore pasted input. + --no-search-header-lines + Searches do not include header lines. + --no-search-header-columns + Searches do not include header columns. + --no-search-headers + Searches do not include header lines or columns. + --no-vbell + Disable the terminal's visual bell. + --redraw-on-quit + Redraw final screen when quitting. + --rscroll=[_C] + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --search-options=[EFKNRW-] + Set default options for every search. + --show-preproc-errors + Display a message if preprocessor exits with an error status. + --proc-backspace + Process backspaces for bold/underline. + --PROC-BACKSPACE + Treat backspaces as control characters. + --proc-return + Delete carriage returns before newline. + --PROC-RETURN + Treat carriage returns as control characters. + --proc-tab + Expand tabs to spaces. + --PROC-TAB + Treat tabs as control characters. + --status-col-width=[_N] + Set the width of the -J status column to _N characters. + --status-line + Highlight or color the entire line containing a mark. + --use-backslash + Subsequent options use backslash as escape char. + --use-color + Enables colored text. + --wheel-lines=[_N] + Each click of the mouse wheel moves _N lines. + --wordwrap + Wrap lines at spaces. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. diff --git a/helpmehelpapplication/.ai/mcp/mcp.json b/helpmehelpapplication/.ai/mcp/mcp.json new file mode 100644 index 00000000..e69de29b diff --git a/helpmehelpapplication/.gitignore b/helpmehelpapplication/.gitignore index e673575a..75408f0c 100644 --- a/helpmehelpapplication/.gitignore +++ b/helpmehelpapplication/.gitignore @@ -1,2 +1,3 @@ .idea/ -target/ \ No newline at end of file +helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseConnection.java +helpmehelpapplication/src/main/resources/fxml/test/ diff --git a/helpmehelpapplication/App_startup_and_api_sync.puml b/helpmehelpapplication/App_startup_and_api_sync.puml new file mode 100644 index 00000000..fc1956dd --- /dev/null +++ b/helpmehelpapplication/App_startup_and_api_sync.puml @@ -0,0 +1,46 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title Application startup and organisation data sync from API + +participant "HmHApplication" as App +participant "DatabaseSetup" as Setup +participant "DatabaseConnection" as DBConn +participant "APICharityScraper" as API +participant "APIToDatabaseService" as Sync +database "MySQL DB" as DB +collections "CharityRegistry" as Registry + +App -> Setup : testConnection() +Setup -> DBConn : getMySqlConnection() +DBConn --> Setup : connection +Setup --> App : OK + +App -> Setup : createTables() +Setup -> DB : CREATE TABLE IF NOT EXISTS ... +DB --> Setup : tables ready +Setup --> App : OK + +App -> API : checkConnection() +API --> App : true +App -> API : getJSONData() +API --> App : JSON payload +App -> API : parseJSON(json) +API --> App : CharityRegistry + +App -> Sync : addAPIDataToTable(Registry.getAllCharities()) +activate Sync +Sync -> DBConn : getMySqlConnection() +DBConn --> Sync : SQL connection +loop For each charity from API + Sync -> DB : INSERT/UPDATE Charities + Sync -> DB : INSERT/UPDATE CharityVanity +end +Sync -> DB : CREATE TEMP TABLE temp_api_charities +Sync -> DB : INSERT current org numbers into temp table +Sync -> DB : DELETE stale charities not referenced elsewhere +DB --> Sync : commit complete +Sync --> App : Sync finished +Deactivate Sync +@enduml diff --git a/helpmehelpapplication/Authentication_backend_flow.puml b/helpmehelpapplication/Authentication_backend_flow.puml new file mode 100644 index 00000000..6668108d --- /dev/null +++ b/helpmehelpapplication/Authentication_backend_flow.puml @@ -0,0 +1,77 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title User registration, login and logout backend flow + +actor User +participant "UI / Controller" as UI +participant "AuthenticationService" as Auth +participant "UserSelect" as UserSelect +participant "UserDAO" as UserDAO +database "MySQL DB" as DB + +== Registration == +User -> UI : Submit displayName, username, email, password +UI -> Auth : register(displayName, username, email, password) +activate Auth +Auth -> UserSelect : isUsernameTaken(username) +activate UserSelect +UserSelect -> DB : SELECT UUID_User FROM User WHERE user_name = username +DB --> UserSelect : username exists / not found +UserSelect --> Auth : true / false +Deactivate UserSelect + +alt Username already taken + Auth --> UI : false + UI --> User : Show registration failed +else Username available + Auth -> UserDAO : registerUser(new User) + activate UserDAO + UserDAO -> DB : INSERT INTO User + UserDAO -> DB : INSERT INTO Settings + DB --> UserDAO : insert result + UserDAO --> Auth : success / failure + deactivate UserDAO + + alt Registration successful + Auth -> Auth : currentUser = newUser + Auth --> UI : true + UI --> User : Show registration successful + else Registration failed + Auth --> UI : false + UI --> User : Show registration failed + end +end +Deactivate Auth + +== Login == +User -> UI : Submit username and password +UI -> Auth : login(username, password) +activate Auth +Auth -> UserSelect : getUserFromDBUsernameAndPassword(username, password) +activate UserSelect +UserSelect -> DB : SELECT User + Settings + Messages +DB --> UserSelect : matching user rows +UserSelect --> Auth : User / null +Deactivate UserSelect + +alt Matching user found + Auth -> Auth : currentUser = user + Auth --> UI : true + UI --> User : Show logged-in state +else No match + Auth --> UI : false + UI --> User : Show login failed +end +Deactivate Auth + +== Logout == +User -> UI : Click logout +UI -> Auth : logout() +activate Auth +Auth -> Auth : currentUser = null +Auth --> UI : logged out +UI --> User : Return to logged-out state +Deactivate Auth +@enduml diff --git a/helpmehelpapplication/Class_diagram.puml b/helpmehelpapplication/Class_diagram.puml new file mode 100644 index 00000000..771ac72a --- /dev/null +++ b/helpmehelpapplication/Class_diagram.puml @@ -0,0 +1,127 @@ +@startuml +skinparam classAttributeIconSize 0 + +' ====================== +' CONTROLLERS +' ====================== +package "Controllers" { + class OrganisationController { + +getAll() + +getById(id) + +search(query) + } + + class DonationController { + +createDonation() + +confirmDonation() + } + + class AuthController { + +login() + +register() + +logout() + } +} + +' ====================== +' SERVICES +' ====================== +package "Services" { + class OrganisationService { + +getOrganisations() + +getOrganisationDetails() + +searchOrganisations() + } + + class DonationService { + +createDonationIntent() + +confirmDonation() + } + + class AuthService { + +authenticate() + +createUser() + } + + class ScraperService { + +fetchFromAPI() + +enrichData() + } +} + +' ====================== +' REPOSITORIES +' ====================== +package "Repositories" { + class OrganisationRepository { + +findAll() + +findById() + +search() + } + + class DonationRepository { + +save() + +findByUser() + } + + class UserRepository { + +findByEmail() + +save() + } +} + +' ====================== +' MODELS / ENTITIES +' ====================== +package "Models" { + class Organisation { + id + name + description + category + imageUrl + } + + class Donation { + id + amount + userId + organisationId + createdAt + } + + class User { + id + email + passwordHash + } +} + +' ====================== +' RELATIONSHIPS +' ====================== + +' Controller -> Service +OrganisationController --> OrganisationService +DonationController --> DonationService +AuthController --> AuthService + +' Service -> Repository +OrganisationService --> OrganisationRepository +DonationService --> DonationRepository +DonationService --> OrganisationRepository +AuthService --> UserRepository + +' Service -> External logic +OrganisationService --> ScraperService + +' Repository -> Model +OrganisationRepository --> Organisation +DonationRepository --> Donation +UserRepository --> User + +' Model relations +Donation --> User +Donation --> Organisation + +@enduml \ No newline at end of file diff --git a/helpmehelpapplication/Frontpage_load.puml b/helpmehelpapplication/Frontpage_load.puml new file mode 100644 index 00000000..0175096b --- /dev/null +++ b/helpmehelpapplication/Frontpage_load.puml @@ -0,0 +1,38 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title User opens front page and the app loads featured organisations + +actor User +participant "FrontpageController" as Frontpage +participant "DatabaseConnection" as DBConn +participant "CharitySelect" as CharitySelect +participant "DonationSelect" as DonationSelect +database "MySQL DB" as DB + +User -> Frontpage : Open application / front page +activate Frontpage +Frontpage -> DBConn : create connection +DBConn --> Frontpage : connection helper + +Frontpage -> CharitySelect : getCharitiesFromDB() +activate CharitySelect +CharitySelect -> DB : SELECT charities + charity vanity + categories + feedback +DB --> CharitySelect : CharityRegistry +CharitySelect --> Frontpage : CharityRegistry +Deactivate CharitySelect + +Frontpage -> DonationSelect : getDonationFromDB() +activate DonationSelect +DonationSelect -> DB : SELECT donations + charity + user +DB --> DonationSelect : DonationRegistry +DonationSelect --> Frontpage : DonationRegistry +Deactivate DonationSelect + +Frontpage -> Frontpage : displayCharities(allCharities) +Frontpage -> Frontpage : choose random featured charity +Frontpage -> Frontpage : calculate totals and pre-approved percentage +Frontpage --> User : Show cards, featured charity and statistics +Deactivate Frontpage +@enduml diff --git a/helpmehelpapplication/Full_organisation_enrichment_scrape.puml b/helpmehelpapplication/Full_organisation_enrichment_scrape.puml new file mode 100644 index 00000000..087c774d --- /dev/null +++ b/helpmehelpapplication/Full_organisation_enrichment_scrape.puml @@ -0,0 +1,39 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title Full organisation enrichment scrape + +actor "System / Developer" as Operator +participant "FullCharityScrape" as FullScrape +participant "APICharityScraper" as API +participant "URLCharityScraper" as URLScraper +participant "LogoDownloader" as Logo +collections "CharityRegistry" as Registry +collections "Charity" as Charity + +Operator -> FullScrape : getAPIAndURLCharityData() +activate FullScrape +FullScrape -> API : checkConnection() +API --> FullScrape : true +FullScrape -> API : getJSONData() +API --> FullScrape : JSON payload +FullScrape -> API : parseJSON(json) +API --> FullScrape : CharityRegistry + +loop For each charity in registry + FullScrape -> URLScraper : new URLCharityScraper(charity.getURL()) + FullScrape -> URLScraper : scrapeCharityPage() + URLScraper --> FullScrape : description, categories, logoURL, keyValues + FullScrape -> Logo : downloadImageAsBlob(logoURL) + Logo --> FullScrape : logo blob + FullScrape -> Charity : setDescription(...) + FullScrape -> Charity : setCategory(...) + FullScrape -> Charity : setLogoURL(...) + FullScrape -> Charity : setKeyValues(...) + FullScrape -> Charity : setLogoBlob(...) +end + +FullScrape --> Operator : Fully enriched CharityRegistry +Deactivate FullScrape +@enduml diff --git a/helpmehelpapplication/Organization_message.puml b/helpmehelpapplication/Organization_message.puml deleted file mode 100644 index 81ef5b9a..00000000 --- a/helpmehelpapplication/Organization_message.puml +++ /dev/null @@ -1,31 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title Messaging between Organisation and User - -actor Organisation as Org -actor User -participant "Organization Portal (UI)" as OrgUI -participant "User App (UI)" as UserUI -participant "Messaging Service" as MsgSvc -database "Messages DB" as MsgDB -participant "Notification Service" as Notify - -Org -> OrgUI: Write message to user -OrgUI -> MsgSvc: sendMessage(orgId, userId, content) -MsgSvc -> MsgDB: store message -MsgDB --> MsgSvc: stored -MsgSvc -> Notify: notifyUser(userId, "New message") -Notify --> MsgSvc: queued -MsgSvc --> OrgUI: sent OK -OrgUI --> Org: Message sent - -User -> UserUI: Open Inbox -UserUI -> MsgSvc: getInbox(userId) -MsgSvc -> MsgDB: fetch messages for userId -MsgDB --> MsgSvc: messages -MsgSvc --> UserUI: messages -UserUI --> User: Display inbox - -@enduml \ No newline at end of file diff --git a/helpmehelpapplication/Organization_onboard.puml b/helpmehelpapplication/Organization_onboard.puml deleted file mode 100644 index fe48d6f3..00000000 --- a/helpmehelpapplication/Organization_onboard.puml +++ /dev/null @@ -1,46 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title Organisation onboarding - -actor Organisation as Org -participant "Organization Portal (UI)" as UI -participant "Authentication Service" as Auth -participant "Email Service" as Mail -participant "Organisation Service" as OrgSvc -database "Organisation DB" as OrgDB -participant "Payment Provider" as Pay - -Org -> UI: Open Organisation Portal Dashboard -UI --> Org: Show portal dashboard - -Org -> UI: Register organisation account -UI -> Auth: register(orgEmail, password) -Auth --> UI: accountCreated + verificationToken - -Auth -> Mail: sendVerificationEmail(orgEmail, token) -Mail --> Auth: sent - -Org -> UI: Click verification link (token) -UI -> Auth: verifyEmail(token) -Auth --> UI: verified OK - -Org -> UI: Create organisation profile (name, desc, category, media) -UI -> OrgSvc: createProfile(profileData) -OrgSvc -> OrgDB: insert profile -OrgDB --> OrgSvc: created -OrgSvc --> UI: profileCreated -UI --> Org: Profile created - -Org -> UI: Set up payout account -UI -> Pay: createConnectedAccount(orgData) -Pay --> UI: connectedAccountId + status - -UI -> OrgSvc: savePayoutAccount(orgId, connectedAccountId) -OrgSvc -> OrgDB: update payout info -OrgDB --> OrgSvc: saved -OrgSvc --> UI: payoutSetupSaved -UI --> Org: Payout setup complete - -@enduml diff --git a/helpmehelpapplication/Organization_update_profile.puml b/helpmehelpapplication/Organization_update_profile.puml deleted file mode 100644 index e6ef6f06..00000000 --- a/helpmehelpapplication/Organization_update_profile.puml +++ /dev/null @@ -1,26 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title Organisation updates profile - -actor Organisation as Org -participant "Organization Portal (UI)" as UI -participant "Organisation Service" as OrgSvc -database "Organisation DB" as OrgDB - -Org -> UI: Open My Organisation Profile -UI -> OrgSvc: getProfile -OrgSvc -> OrgDB: load profile -OrgDB --> OrgSvc: profile data -OrgSvc --> UI: profile data -UI --> Org: Show profile - -Org -> UI: Edit profile fields + upload media -UI -> OrgSvc: updateProfile -OrgSvc -> OrgDB: update profile -OrgDB --> OrgSvc: updated -OrgSvc --> UI: update OK -UI --> Org: Show updated profile - -@enduml diff --git a/helpmehelpapplication/Search_and_browse_organisation.puml b/helpmehelpapplication/Search_and_browse_organisation.puml new file mode 100644 index 00000000..6d297588 --- /dev/null +++ b/helpmehelpapplication/Search_and_browse_organisation.puml @@ -0,0 +1,82 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title User searches and browses organisations + +actor User +participant "FrontpageController / CharityPageController / DonationPageController" as SourceUI +participant "LoaderScene" as Loader +participant "AvailableOrganizationController" as Available +participant "DatabaseConnection" as DBConn +participant "CharitySelect" as CharitySelect +database "MySQL DB" as DB + +User -> SourceUI : Enter search text and press search +SourceUI -> Loader : LoadScene("availableOrganization", query) +Loader -> Available : initialize() +activate Available +Available -> DBConn : create connection +DBConn --> Available : connection helper +Available -> CharitySelect : getCharitiesFromDB() +activate CharitySelect +CharitySelect -> DB : SELECT charities + charity vanity + categories + feedback +DB --> CharitySelect : CharityRegistry +CharitySelect --> Available : CharityRegistry +Deactivate CharitySelect + +Available -> Available : setInitialSearch(query) +Available -> Available : filterCharities(query) +Available -> Available : displayCharities(matches) +Available --> User : Show matching organisation cards + +loop While user edits the search field + User -> Available : Update search text + Available -> Available : filterCharities(newValue) + Available -> Available : displayCharities(filtered list) + Available --> User : Refresh result list +end + +deactivate Available +@enduml +@startuml +!theme plain +skinparam backgroundColor white + +title User searches and browses organisations + +actor User +participant "FrontpageController / CharityPageController / DonationPageController" as SourceUI +participant "LoaderScene" as Loader +participant "AvailableOrganizationController" as Available +participant "DatabaseConnection" as DBConn +participant "CharitySelect" as CharitySelect +database "MySQL DB" as DB + +User -> SourceUI : Enter search text and press search +SourceUI -> Loader : LoadScene("availableOrganization", query) +Loader -> Available : initialize() +activate Available +Available -> DBConn : create connection +DBConn --> Available : connection helper +Available -> CharitySelect : getCharitiesFromDB() +activate CharitySelect +CharitySelect -> DB : SELECT charities + charity vanity + categories + feedback +DB --> CharitySelect : CharityRegistry +CharitySelect --> Available : CharityRegistry +Deactivate CharitySelect + +Available -> Available : setInitialSearch(query) +Available -> Available : filterCharities(query) +Available -> Available : displayCharities(matches) +Available --> User : Show matching organisation cards + +loop While user edits the search field + User -> Available : Update search text + Available -> Available : filterCharities(newValue) + Available -> Available : displayCharities(filtered list) + Available --> User : Refresh result list +end + +deactivate Available +@enduml diff --git a/helpmehelpapplication/User_authenticator.puml b/helpmehelpapplication/User_authenticator.puml deleted file mode 100644 index 403814fd..00000000 --- a/helpmehelpapplication/User_authenticator.puml +++ /dev/null @@ -1,36 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title User authentication for for signin and Login - -actor User -participant "Desktop App (UI)" as UI -participant "Authenticator Service" as Auth -database "User DB" as UDB - -User -> UI: Open Dashboard -UI --> User: Show dashboard - -User -> UI: Click Login -UI --> User: Show Welcome/Login page - -User -> UI: Go to Sign In -UI --> User: Show Sign In form - -User -> UI: Submit credentials -UI -> Auth: signIn(email, password) -Auth -> UDB: validate credentials -UDB --> Auth: valid -Auth --> UI: session/token -UI --> User: Logged in (Dashboard updated) - -User -> UI: Click "My Profile" (from Dashboard) -UI --> User: Show Profile - -User -> UI: Click Logout -UI -> Auth: logout(session) -Auth --> UI: session terminated -UI --> User: Redirect to Dashboard - -@enduml diff --git a/helpmehelpapplication/User_browser.puml b/helpmehelpapplication/User_browser.puml deleted file mode 100644 index d279b7e8..00000000 --- a/helpmehelpapplication/User_browser.puml +++ /dev/null @@ -1,56 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title User explores organisations - -actor User -participant "Desktop App (UI)" as UI -participant "Organisation Service" as OrgSvc -database "Organisation DB" as OrgDB - -User -> UI: Open Dashboard -UI --> User: Show dashboard - -User -> UI: Click "Browse Organisations" -UI -> OrgSvc: getFeaturedOrgs() -OrgSvc -> OrgDB: query featured orgs -OrgDB --> OrgSvc: org list -OrgSvc --> UI: org list -UI --> User: Show organisations list - -alt User chooses Category - User -> UI: Select category - UI -> OrgSvc: getOrgsByCategory(category) - OrgSvc -> OrgDB: query orgs by category - OrgDB --> OrgSvc: results - OrgSvc --> UI: results - UI --> User: Show filtered list -end - -alt User uses Filter/Sort - User -> UI: Set filters/sort - UI -> OrgSvc: getOrgsFiltered(filters, sort) - OrgSvc -> OrgDB: query with filters/sort - OrgDB --> OrgSvc: results - OrgSvc --> UI: results - UI --> User: Show filtered list -end - -alt User searches from Dashboard or list - User -> UI: Search organisations (query) - UI -> OrgSvc: searchOrgs(query) - OrgSvc -> OrgDB: fulltext/search query - OrgDB --> OrgSvc: results - OrgSvc --> UI: results - UI --> User: Show search results -end - -User -> UI: Open organisation page -UI -> OrgSvc: getOrganisationDetails(orgId) -OrgSvc -> OrgDB: load org details -OrgDB --> OrgSvc: org details -OrgSvc --> UI: org details -UI --> User: Show organisation page - -@enduml \ No newline at end of file diff --git a/helpmehelpapplication/User_donate.puml b/helpmehelpapplication/User_donate.puml deleted file mode 100644 index f856d182..00000000 --- a/helpmehelpapplication/User_donate.puml +++ /dev/null @@ -1,41 +0,0 @@ - -'https://plantuml.com/sequence-diagram - -@startuml -title User donation - -actor User -participant "Desktop App (UI)" as UI -participant "Donation Service" as DonSvc -participant "Payment Provider" as Pay -database "Donation DB" as DonDB -participant "Organisation Service" as OrgSvc - -User -> UI: Click "Donate" -UI --> User: Show donation form - -User -> UI: Enter amount + confirm -UI -> DonSvc: createDonationIntent(userId, orgId, amount) - -DonSvc -> OrgSvc: validateOrganisation(orgId) -OrgSvc --> DonSvc: OK - -DonSvc -> Pay: createPaymentIntent(amount) -Pay --> DonSvc: paymentIntentId + clientSecret - -DonSvc --> UI: clientSecret -UI -> Pay: Complete payment (clientSecret) -Pay --> UI: Payment success - -UI -> DonSvc: confirmDonation(paymentIntentId) -DonSvc -> Pay: verifyPayment(paymentIntentId) -Pay --> DonSvc: verified OK - -DonSvc -> DonDB: store donation record -DonDB --> DonSvc: stored - -DonSvc --> UI: Donation confirmation -UI --> User: Show "Thank you" + receipt - -@enduml - diff --git a/helpmehelpapplication/User_donation.puml b/helpmehelpapplication/User_donation.puml new file mode 100644 index 00000000..61b56cf6 --- /dev/null +++ b/helpmehelpapplication/User_donation.puml @@ -0,0 +1,40 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title User donation flow in the current application + +actor User +participant "DonationPageController" as DonationPage +participant "JavaFX Alert" as Alert +participant "LoaderScene" as Loader + +User -> DonationPage : Open donation page for selected charity +DonationPage -> DonationPage : setCharity(charity) +DonationPage --> User : Show charity name and amount field + +User -> DonationPage : Enter amount and click Donate +DonationPage -> DonationPage : Validate input + +alt Invalid amount / empty / not numeric / <= 0 / > 100000 + DonationPage -> Alert : showAlert(ERROR or WARNING) + Alert --> User : Show validation message +else Valid amount + DonationPage -> Alert : Show confirmation dialog + Alert --> User : Confirm donation? + + alt User cancels + Alert --> DonationPage : Cancel + DonationPage --> User : Stay on donation page + else User confirms + Alert --> DonationPage : OK + note right of DonationPage + end note + DonationPage -> Alert : showAlert(INFORMATION, "Thank you!") + Alert --> User : Show success message + DonationPage -> DonationPage : clear amount field + DonationPage -> Loader : LoadScene("FrontPage") + Loader --> User : Show front page + end +end +@enduml diff --git a/helpmehelpapplication/View_organisation_details.puml b/helpmehelpapplication/View_organisation_details.puml new file mode 100644 index 00000000..d833aa73 --- /dev/null +++ b/helpmehelpapplication/View_organisation_details.puml @@ -0,0 +1,29 @@ +@startuml +!theme plain +skinparam backgroundColor white + +title User opens an organisation page + +actor User +participant "OrganizationCardController" as Card +participant "LoaderScene" as Loader +participant "CharityPageController" as CharityPage +collections "Selected Charity object" as Charity + +User -> Card : Click organisation card +Card -> Loader : LoadScene("CharityPage", charity) +Loader -> CharityPage : setCharity(charity) +activate CharityPage +CharityPage -> Charity : getName() +Charity --> CharityPage : charity name +CharityPage -> Charity : getDescription() +Charity --> CharityPage : charity description +CharityPage --> User : Show organisation page + +opt User chooses to donate + User -> CharityPage : Click donate + CharityPage -> Loader : LoadScene("donationPage", charity) +end + +deactivate CharityPage +@enduml diff --git a/helpmehelpapplication/pom.xml b/helpmehelpapplication/pom.xml index 1794a9e3..c1f5d381 100644 --- a/helpmehelpapplication/pom.xml +++ b/helpmehelpapplication/pom.xml @@ -33,7 +33,7 @@ org.seleniumhq.selenium selenium-java - 4.41.0 + 4.43.0 com.opencsv @@ -62,6 +62,13 @@ 2.4.240 test + + + org.mockito + mockito-junit-jupiter + 5.23.0 + test + @@ -109,8 +116,25 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.13 + + + + prepare-agent + + + + report + test + + report + + + + - - \ No newline at end of file diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/DAO/DonationDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/DAO/DonationDAO.java deleted file mode 100644 index c99056f9..00000000 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/DAO/DonationDAO.java +++ /dev/null @@ -1,43 +0,0 @@ -package ntnu.systemutvikling.team6.DAO; - -import java.sql.*; -import java.util.UUID; -import ntnu.systemutvikling.team6.database.DatabaseConnection; -import ntnu.systemutvikling.team6.models.Charity; - -/** - * This class is responsible for sending concurrent information about the donation to the Donation - * Database. Usally called from the DonationPageController, where the user confirms their donation. - */ -public class DonationDAO { - private static final DatabaseConnection connection = new DatabaseConnection(); - - /** - * Gets the total ammount of donations for a given charity, and sends it to the database throught - * MySQL. - * - * @param charity - * @param amount - */ - public static void addDonation(Charity charity, double amount) { - String sql_query = - """ - INSERT INTO Donations (UUID_Donations, amount, date, Charities_UUID_charities) - VALUES (?, ?, ?, ?) - """; - try (Connection conn = connection.getMySqlConnection(); - PreparedStatement ps = conn.prepareStatement(sql_query)) { - conn.setAutoCommit(false); - - ps.setString(1, UUID.randomUUID().toString()); - ps.setDouble(2, amount); - ps.setDate(3, new Date(System.currentTimeMillis())); - ps.setString(4, charity.getUUID().toString()); - - ps.executeUpdate(); - conn.commit(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } -} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/HmHApplication.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/HmHApplication.java index 293aa2da..92c37b29 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/HmHApplication.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/HmHApplication.java @@ -9,17 +9,27 @@ import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; -import ntnu.systemutvikling.team6.database.DatabaseManager; -import ntnu.systemutvikling.team6.models.Charity; -import ntnu.systemutvikling.team6.models.CharityRegistry; -import ntnu.systemutvikling.team6.scraper.APICharityScraper; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.database.DAO.UserDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.database.DatabaseSetup; +import ntnu.systemutvikling.team6.scraper.FullCharityScrape; +import ntnu.systemutvikling.team6.service.APIToDatabaseService; +import ntnu.systemutvikling.team6.service.AuthenticationService; public class HmHApplication extends Application { @Override public void start(Stage stage) throws Exception { + DatabaseConnection conn = new DatabaseConnection(); + AuthenticationService authToken = new AuthenticationService(new UserDAO(conn)); + FXMLLoader fxmlLoader = new FXMLLoader(HmHApplication.class.getResource("/fxml/frontPage.fxml")); Scene scene = new Scene(fxmlLoader.load()); + + BaseController controller = fxmlLoader.getController(); + controller.setAuthToken(authToken); + Image icon = new Image( Objects.requireNonNull(HmHApplication.class.getResource("/images/Logo.png")) @@ -31,13 +41,23 @@ public void start(Stage stage) throws Exception { stage.setFullScreen(true); stage.show(); + // Re-enter fullscreen when restored from taskbar + stage + .iconifiedProperty() + .addListener( + (obs, wasIconified, isNowIconified) -> { + if (!isNowIconified) { + stage.setFullScreen(true); + } + }); } @Override public void init() { /* Test and create tables to MySQL if ain't any */ try { - DatabaseManager db = new DatabaseManager(); + DatabaseConnection conn = new DatabaseConnection(); + DatabaseSetup db = new DatabaseSetup(conn); db.testConnection(); db.createTables(); } catch (Exception e) { @@ -46,19 +66,29 @@ public void init() { /* Test and get data from Innsamlingkontrollen API */ try { HttpClient https = HttpClient.newHttpClient(); - APICharityScraper scraper = new APICharityScraper(https); - DatabaseManager db = new DatabaseManager(); + // APICharityScraper scraper = new APICharityScraper(https); + FullCharityScrape scraper = new FullCharityScrape(); - if (scraper.checkConnection()) { + DatabaseConnection conn = new DatabaseConnection(); + APIToDatabaseService db = new APIToDatabaseService(conn); + + if (scraper.getAPIScraper().checkConnection()) { + /* + if (scraper.checkConnection()) { CharityRegistry charityRegistry = scraper.parseJSON(scraper.getJSONData()); for (Charity charity : charityRegistry.getAllCharities()) { System.out.println(charity.getName()); } - db.addAPIDataToTable(charityRegistry.getAllCharities()); + */ + + // Comment out the two below to use already generated database. + // CharityRegistry charityRegistry = scraper.getAPIAndURLCharityData(); + // db.addAPIDataToTable(charityRegistry.getAllCharities()); } } catch (Exception e) { e.printStackTrace(); } + System.out.println("-- \n Init complete \n --"); } public static void main(String[] args) { diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AboutPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AboutPageController.java new file mode 100644 index 00000000..395466ce --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AboutPageController.java @@ -0,0 +1,17 @@ +package ntnu.systemutvikling.team6.controller; + +import javafx.fxml.FXML; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.FooterController; +import ntnu.systemutvikling.team6.controller.components.NavbarController; + +public class AboutPageController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + @Override + protected void authTokenisSet() { + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.java new file mode 100644 index 00000000..230ef931 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/AvailableOrganizationController.java @@ -0,0 +1,157 @@ +package ntnu.systemutvikling.team6.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.TextField; +import javafx.scene.layout.FlowPane; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.CharityDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; + +/** + * This controller represents the available organization page, where the user can search for a + * charity and choose to donate to it. It also has a button to return to the front page. The user + * can search for a charity by typing in the search field, and the charities that match the search + * query will be displayed. The user can click on a charity to see more details about it, or click + * on the featured charity to see more details about it. The user can also switch to the charity + * page or donation page for the selected charity. + */ +public class AvailableOrganizationController extends BaseController { + + @FXML private TextField searchField; + @FXML private FlowPane cardsContainer; + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + private Charity charity; + private List allCharities; + + @Override + protected void authTokenisSet() { + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } + + /** + * This method is used to initialize the available organization page. It retrieves all charities + * from the database and sets up a listener on the search field to filter the charities based on + * the user's input. It also clears the cards container to prepare for displaying the filtered + * charities. The method is called automatically when the page is loaded, and it sets up the + * initial state of the page. + */ + @FXML + public void initialize() { + DatabaseConnection conn = new DatabaseConnection(); + CharityDAO db = new CharityDAO(conn); + CharityRegistry charities = db.getCharitiesFromDB(); + allCharities = charities.getAllCharities(); + + cardsContainer.getChildren().clear(); + + searchField + .textProperty() + .addListener( + (observable, oldValue, newValue) -> displayCharities(filterCharities(newValue))); + } + + /** + * This method filters the charities based on the user's input in the search field. + * + * @param query is the user's input in the search field, which is used to filter the charities. + * @return a list of charities that match the search query. + */ + private List filterCharities(String query) { + List matches = new ArrayList<>(); + + query = query.toLowerCase().trim(); + + if (query.isEmpty()) { + return matches; + } + + for (Charity charity : allCharities) { + String name = charity.getName(); + String description = charity.getDescription(); + + if (name == null || name.isBlank()) { + name = "This one has no name"; + } else { + name = name.toLowerCase(); + } + if (description == null || description.isBlank()) { + description = "This one has no description"; + } else { + description = description.toLowerCase(); + } + + if (name.contains(query) || description.contains(query)) { + matches.add(charity); + } + } + return matches; + } + + /** + * This method displays the charities in the cards container. + * + * @param charities is a list of charities to be displayed. + */ + private void displayCharities(List charities) { + cardsContainer.getChildren().clear(); + + for (Charity charity : charities) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/organizationCard.fxml")); + Parent card = loader.load(); + + OrganizationCardController cardController = loader.getController(); + cardController.setOrganization(charity); + + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + /** + * This method is used to set the initial search query in the search field. + * + * @param query is the initial search query. + */ + @FXML + public void setInitialSearch(String query) { + if (query == null || query.isBlank()) { + return; + } + + searchField.setText(query); + } + + /** + * This method is used to switch to the charity page for the selected charity. + * + * @param event action event from button click + */ + public void switchToCharityPage(ActionEvent event) { + LoaderScene.LoadScene("CharityPage", event, charity, null, authToken); + } + + /** + * This method is used to switch to the donation page. + * + * @param event action event from button click + */ + @FXML + public void switchToDonationPage(ActionEvent event) { + LoaderScene.LoadScene("DonationPage", event, charity, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java index 8eb853f6..40a09f97 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java @@ -1,22 +1,67 @@ package ntnu.systemutvikling.team6.controller; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.shape.Arc; +import javafx.scene.shape.Rectangle; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.FooterController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; import ntnu.systemutvikling.team6.models.Charity; /** * This controller represents the charity page, where the user can read about the charity and choose * to donate to it. It also has a button to return to the front page. */ -public class CharityPageController { +public class CharityPageController extends BaseController { + @FXML private TextField charitySearchField; + @FXML private Label CharityDescription; @FXML private Label CharityName; + @FXML private ImageView CharityLogo; + + @FXML private Hyperlink CharityURL; + + @FXML private Arc keyValueInnsamlingArc; + + @FXML private Label keyValueInnsamlingLabel; + + @FXML private Arc keyValueAdminArc; + + @FXML private Label keyValueAdminLabel; + + @FXML private Arc keyValueFormaalArc; + + @FXML private Label keyValueFormaalLabel; + + @FXML private VBox categoriesContainer; + + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + @FXML public void initialize() {} + @Override + protected void authTokenisSet() { + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } + private Charity charity; /** @@ -27,7 +72,7 @@ public void initialize() {} * front page when the user clicks on a charity, to set the charity that is being displayed on the * page. * - * @param charity + * @param charity the charity to be displayed */ @FXML public void setCharity(Charity charity) { @@ -35,27 +80,137 @@ public void setCharity(Charity charity) { CharityDescription.setText(charity.getDescription()); CharityName.setText(charity.getName()); + + if (this.charity.getLogoBlob() != null) { + ByteArrayInputStream logoByteStream = new ByteArrayInputStream(this.charity.getLogoBlob()); + Image CharityLogoImage = new Image(logoByteStream); + this.CharityLogo.setImage(CharityLogoImage); + } else { + String placeholderImagePath = + Objects.requireNonNull(getClass().getResource("/images/leggTilBilde.jpg")) + .toExternalForm(); + Image placeholderImage = new Image(placeholderImagePath); + this.CharityLogo.setImage(placeholderImage); + } + + // Sets key values to a List + String input = charity.getKeyValues(); + if (input != null) { + + String[] parts = input.split(":"); + List numbers = new ArrayList<>(); + + for (String part : parts) { + part = part.replace(",", "."); + numbers.add(Double.parseDouble(part)); + } + + // Sets the value of each arc and label + setArc(keyValueInnsamlingArc, numbers.getFirst()); + keyValueInnsamlingLabel.setText(String.format("%.1f%%", numbers.getFirst())); + setArc(keyValueAdminArc, numbers.get(1)); + keyValueAdminLabel.setText(String.format("%.1f%%", numbers.get(1))); + setArc(keyValueFormaalArc, numbers.getLast()); + keyValueFormaalLabel.setText(String.format("%.1f%%", numbers.getLast())); + } + + // Sets the categories + setCategories(charity.getCategory()); } /** - * This method is used to switch to the front page. + * This method is used to switch to the donation page. * * @param event */ + @FXML + public void switchToDonationPage(ActionEvent event) { + System.out.println("Click"); + LoaderScene.LoadScene("donationPage", event, charity, null, authToken); + } + @FXML public void switchToFrontPage(ActionEvent event) { System.out.println("Click"); - LoaderScene.LoadScene("FrontPage", event, charity); + LoaderScene.LoadScene("FrontPage", event, charity, null, authToken); } /** - * This method is used to switch to the donation page. + * This method is used to search for charities based on the input in the search field. * - * @param event + * @param event is the event that triggered the search. */ @FXML - public void switchToDonationPage(ActionEvent event) { - System.out.println("Click"); - LoaderScene.LoadScene("donationPage", event, charity); + private void switchToFeedbackPage(ActionEvent event) { + LoaderScene.LoadScene("giveFeedback", event, charity, null, authToken); + } + + /** + * Opens OS default webbrowser and loads the url of the charity on click. + * + * @param event the onclick event + */ + @FXML + public void handleHomepageClick(ActionEvent event) { + try { + String url = this.charity.getURL(); + java.awt.Desktop.getDesktop().browse(java.net.URI.create(url)); + } catch (Exception e) { + System.out.println("Something went wrong when opening URL."); + e.printStackTrace(); + } + } + + /** + * Creates the labels (and the rectangle surrounding it) for the categories + * + * @param category the String for the category + * @return a fxml object used to populate the category scroll pane + */ + private StackPane createCategoryChip(String category) { + + Rectangle rect = new Rectangle(); + rect.setArcWidth(30); + rect.setArcHeight(30); + rect.setHeight(40); + rect.setWidth(200); + rect.setFill(javafx.scene.paint.Color.web("#F5F5F5")); + rect.setStroke(javafx.scene.paint.Color.web("#4F4F4F")); + + Label label = new Label(category); + label.setStyle("-fx-font-weight: bold; -fx-font-size: 14px;"); + + StackPane stack = new StackPane(rect, label); + stack.setPadding(new javafx.geometry.Insets(5)); + + return stack; + } + + /** + * Takes a list of categories for the charities and populates a scroll pane with labels containing + * the charities. + * + * @param categories the list of categories for the charity + */ + public void setCategories(List categories) { + categoriesContainer.getChildren().clear(); + + for (String category : categories) { + if (category == null || category.isEmpty()) continue; + + StackPane chip = createCategoryChip(category); + categoriesContainer.getChildren().add(chip); + } + } + + /** + * Sets the fill of the arc for the different key values. + * + * @param arc the arc for one of the 3 key values + * @param percent the percentage of the key value + */ + private void setArc(Arc arc, double percent) { + double angle = -360 * (percent / 100.0); + arc.setLength(angle); } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CreateUserPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CreateUserPageController.java new file mode 100644 index 00000000..ba29af77 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CreateUserPageController.java @@ -0,0 +1,86 @@ +package ntnu.systemutvikling.team6.controller; + +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.FooterController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; + +public class CreateUserPageController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + @FXML private TextField firstNameField; + @FXML private TextField emailField; + @FXML private PasswordField passwordField; + @FXML private PasswordField confirmPasswordField; + + @Override + protected void authTokenisSet() { + if (isLoggedin()) { + LoaderScene.LoadScene("frontPage", new ActionEvent(), null, null, authToken); + } + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } + + @FXML + private void handleCreateAccount(ActionEvent event) { + String nameText = firstNameField.getText(); + String emailText = emailField.getText(); + String password = passwordField.getText(); + String confirmPassword = confirmPasswordField.getText(); + + if (nameText.isBlank() + || emailText.isBlank() + || password.isBlank() + || confirmPassword.isBlank()) { + showAlert(Alert.AlertType.ERROR, "Empty input", "Please fill out all fields"); + return; + } + + if (emailText == null + || emailText.isBlank() + || !emailText.contains("@") + || !emailText.contains(".")) { + showAlert(Alert.AlertType.ERROR, "Invalid Email", "Please enter a valid email"); + return; + } + + if (!password.equals(confirmPassword)) { + showAlert(Alert.AlertType.ERROR, "Mismatch of password", "Password do not match"); + return; + } + + // login + boolean registerSuccess; + try { + registerSuccess = authToken.register(nameText, emailText, confirmPassword); + } catch (IllegalArgumentException e) { + showAlert( + Alert.AlertType.ERROR, "Email already taken", "Email already taken by another user."); + return; + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (registerSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Sign up sucsess", + "You have registered a new account! Please login with same credentials"); + LoaderScene.LoadScene("loginSite", event, null, null, authToken); + } + } + + @FXML + private void switchToLoginPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("loginSite", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/DonationPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/DonationPageController.java index 839a3e85..12c6e0b3 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/DonationPageController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/DonationPageController.java @@ -1,25 +1,61 @@ package ntnu.systemutvikling.team6.controller; +import java.time.LocalDate; import java.util.Optional; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import ntnu.systemutvikling.team6.DAO.DonationDAO; +import javafx.scene.control.*; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.FooterController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; +import ntnu.systemutvikling.team6.database.DAO.DonationDAO; +import ntnu.systemutvikling.team6.database.DAO.FavouritesDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Donation; +import ntnu.systemutvikling.team6.models.user.User; /** * This controller represents the donation page, where the user can enter a donation amount and * confirm their donation to the charity. It also has a button to return to the front page. */ -public class DonationPageController { +public class DonationPageController extends BaseController { @FXML private Charity charity; @FXML private TextField donatioAmount; @FXML private Label CharityName; + @FXML private ToggleButton heartButton; + @FXML private TextField donationSearchField; + + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + DatabaseConnection conn = new DatabaseConnection(); + private DonationDAO donationSender = new DonationDAO(conn); + private FavouritesDAO favouritesDAO = new FavouritesDAO(conn); + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + populateFields(); + } /** * Initialize method for the donation page. Sets the charity name label to the name of the charity @@ -35,13 +71,27 @@ public void setCharity(Charity charity) { CharityName.setText(charity.getName()); } - /** - * This method is used to switch back to the front page when the user clicks the back button. - * - * @param event - */ - public void switchToFrontPage(ActionEvent event) { - LoaderScene.LoadScene("FrontPage", event, null); + private void populateFields() { + boolean isFavourite = favouritesDAO.isFavourite(authToken.getCurrentUser(), charity); + heartButton.setSelected(isFavourite); + updateHeartIcon(isFavourite); + } + + @FXML + private void onHeartToggle() { + boolean selected = heartButton.isSelected(); + User user = authToken.getCurrentUser(); + if (selected) { + favouritesDAO.addFavourite(user, charity); + } else { + favouritesDAO.removeFavourite(user, charity); + } + + updateHeartIcon(selected); + } + + private void updateHeartIcon(boolean selected) { + heartButton.setText(selected ? "♥" : "♡"); } /** @@ -50,7 +100,7 @@ public void switchToFrontPage(ActionEvent event) { * @param event */ public void switchToCharityPage(ActionEvent event) { - LoaderScene.LoadScene("charityPage", event, charity); + LoaderScene.LoadScene("charityPage", event, charity, null, authToken); } /** @@ -87,6 +137,19 @@ public void Donate(ActionEvent event) { return; } + Optional resultAnonymous = Optional.empty(); + if (authToken.getCurrentUser().getSettings().isAnonymous()) { + Alert confirmAnonymous = new Alert(Alert.AlertType.CONFIRMATION); + confirmAnonymous.setTitle("You're going to donate Anonymously"); + confirmAnonymous.setHeaderText( + "You're about to make an anonymous donation. The charity and other donors will not be able to see your name amd email assosiated with the donation"); + confirmAnonymous.setContentText("Are you sure?"); + resultAnonymous = confirmAnonymous.showAndWait(); + if (resultAnonymous.isPresent() && resultAnonymous.get() == ButtonType.CANCEL) { + return; + } + } + Alert confirm = new Alert(Alert.AlertType.CONFIRMATION); confirm.setTitle("Confirm Donation"); confirm.setHeaderText("You're about to donate " + amount + " to " + charity.getName()); @@ -94,40 +157,31 @@ public void Donate(ActionEvent event) { Optional result = confirm.showAndWait(); if (result.isPresent() && result.get() == ButtonType.OK) { - // Process donation - processDonation(charity, amount); + Donation donation = + new Donation(amount, LocalDate.now(), charity, authToken.getCurrentUser()); + donationSender.addDonation(donation); showAlert( Alert.AlertType.INFORMATION, "Thank you!", "You have donated " + amount + " to " + charity.getName()); donatioAmount.clear(); - LoaderScene.LoadScene("FrontPage", event, null); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); } } /** - * Invoke DAO object to add the donation to the database. This method is called from the Donate - * method after the user confirms their donation. + * This method is used to handle the search action when the user clicks the search button. * - * @param charity - * @param amount + * @param event is the event that triggered the search. */ - public void processDonation(Charity charity, double amount) { - DonationDAO.addDonation(charity, amount); - } + @FXML + public void handleSearch(ActionEvent event) { + String query = donationSearchField.getText().trim(); - /** - * Show an JavaFx alert dialog with the specified type, title, and message. - * - * @param type - * @param title - * @param message - */ - private void showAlert(Alert.AlertType type, String title, String message) { - Alert alert = new Alert(type); - alert.setTitle(title); - alert.setHeaderText(null); - alert.setContentText(message); - alert.showAndWait(); + if (query.isEmpty()) { + return; + } + + LoaderScene.LoadScene("availableOrganization", event, null, query, authToken); } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/FrontpageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/FrontpageController.java index f8ffc2a7..aa7fa05d 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/FrontpageController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/FrontpageController.java @@ -1,17 +1,26 @@ package ntnu.systemutvikling.team6.controller; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.Random; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; +import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; -import ntnu.systemutvikling.team6.database.DatabaseManager; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.CategoryDAO; +import ntnu.systemutvikling.team6.database.DAO.CharityDAO; +import ntnu.systemutvikling.team6.database.DAO.DonationDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; import ntnu.systemutvikling.team6.models.Charity; -import ntnu.systemutvikling.team6.models.CharityRegistry; import ntnu.systemutvikling.team6.models.Donation; -import ntnu.systemutvikling.team6.models.DonationRegistry; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; +import ntnu.systemutvikling.team6.models.registry.DonationRegistry; /** * Landing page's controller. This is the first page the user sees when they open the application. @@ -20,70 +29,93 @@ * it, or click on the featured charity to see more details about it. It also has buttons to switch * to the charity page and the donation page for the featured charity */ -public class FrontpageController { +public class FrontpageController extends BaseController { @FXML private Charity featuredCharity; - @FXML private FlowPane cardsContainer; - @FXML private Label Carosel_Organisasjon; - @FXML private Label Carosel_Beskrivelse; - @FXML private Label Total_Orgnisasjon; - @FXML private Label Total_Donations; - @FXML private Label PreApproved_Percentage; + @FXML private CheckBox verifiedFilter; + @FXML private javafx.scene.layout.VBox categoryList; + private final List selectedCategories = new ArrayList<>(); + + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + private List allCharities = new ArrayList<>(); + + @Override + protected void authTokenisSet() { + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + loadPage(); + } + /** * Initialize method for the front page. This method is called when the front page is loaded. It * retrieves the list of charities and donations from the database. The list of charities is * displayed as a list of cards, where each card represents a charity from the - * Innsamlingskontrollen A random charity is selected to be featured on the page, and its name and - * description are displayed in the carousel section. The total number of charities, total amount - * of donations, and percentage of pre-approved charities are also displayed on the page. + * Innsamlingskontrollen. A random charity is selected to be featured on the page, and its name + * and description are displayed in the carousel section. The total number of charities, total + * amount of donations, and percentage of pre-approved charities are also displayed on the page. */ @FXML - public void initialize() { - try { - DatabaseManager db = new DatabaseManager(); - CharityRegistry Charities = db.getCharitiesFromDB(); - DonationRegistry Donations = db.getDonationFromDB(); - for (Charity ch : Charities.getAllCharities()) { - - FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/organizationCard.fxml")); - - Parent card = loader.load(); + public void initialize() {} - OrganizationCardController cardController = loader.getController(); + private void loadPage() { + try { + DatabaseConnection conn = new DatabaseConnection(); + CharityDAO cdb = new CharityDAO(conn); + DonationDAO ddb = new DonationDAO(conn); + CategoryDAO categoryselect = new CategoryDAO(conn); + CharityRegistry charities = cdb.getCharitiesFromDB(); + DonationRegistry donations = ddb.getDonationFromDB(); + List categories = categoryselect.getCategoriesFromDB(); + categories.sort(String::compareToIgnoreCase); + + for (String category : categories) { + CheckBox cb = new CheckBox(category); + cb.setStyle("-fx-font-size: 12; -fx-padding: 10 0 0 20; -fx-text-fill: black"); + + cb.setOnAction( + e -> { + if (cb.isSelected()) { + selectedCategories.add(category); + } else { + selectedCategories.remove(category); + } + displayCharities(getFilteredCharities()); + }); + + categoryList.getChildren().add(cb); + } - // System.out.println("Added Name: " + ch.getName() + " Added Description: " + - // ch.getDescription()); - cardController.setOrganization(ch); + allCharities = new ArrayList<>(charities.getAllCharities()); + displayCharities(allCharities); - cardsContainer.getChildren().add(card); - } - int Charities_size = Charities.getAllCharities().size(); + int charitiesSize = charities.getAllCharities().size(); Random random = new Random(); - int randomIndex = random.nextInt(Charities_size); - Charity randomCharity = Charities.getAllCharities().get(randomIndex); + int randomIndex = random.nextInt(charitiesSize); + Charity randomCharity = charities.getAllCharities().get(randomIndex); this.featuredCharity = randomCharity; Carosel_Organisasjon.setText(randomCharity.getName()); Carosel_Beskrivelse.setText(randomCharity.getDescription()); - Total_Orgnisasjon.setText(Integer.toString(Charities_size)); + Total_Orgnisasjon.setText(Integer.toString(charitiesSize)); Total_Donations.setText( Double.toString( - Donations.getAllDonations().stream().mapToDouble(Donation::getAmount).sum())); + donations.getAllDonations().stream().mapToDouble(Donation::getAmount).sum())); PreApproved_Percentage.setText( String.format( "%.2f", - Charities.getAllCharities().stream().filter(Charity::getPreApproved).count() + charities.getAllCharities().stream().filter(Charity::getPreApproved).count() * 100.0 - / Charities_size) + / charitiesSize) + "%"); - } catch (Exception e) { e.printStackTrace(); } @@ -95,7 +127,7 @@ public void initialize() { * @param event */ public void switchToCharityPage(ActionEvent event) { - LoaderScene.LoadScene("CharityPage", event, featuredCharity); + LoaderScene.LoadScene("CharityPage", event, featuredCharity, null, authToken); } /** @@ -104,6 +136,80 @@ public void switchToCharityPage(ActionEvent event) { * @param event */ public void switchToDonationPage(ActionEvent event) { - LoaderScene.LoadScene("DonationPage", event, featuredCharity); + LoaderScene.LoadScene("DonationPage", event, featuredCharity, null, authToken); + } + + /** + * This method is used to filter the charities based on the selected filters. + * + * @param event is the event that triggered the filter. + */ + @FXML + public void handleCategoryFilterChange(ActionEvent event) { + displayCharities(getFilteredCharities()); + } + + /** + * This method is used to filter the charities based on the selected filters. + * + *

    The filters are whether the charity was pre-verified, or if it falls under one (or more) of + * the given categories. + * + *

    The check checks whether the given charity has ALL filters. If one does not apply, the + * charity is rejected. + * + * @return a list of filtered charities. + */ + private List getFilteredCharities() { + + List filtered = new ArrayList<>(); + + for (Charity charity : allCharities) { + + if (verifiedFilter.isSelected() && !charity.getPreApproved()) { + continue; + } + + if (!selectedCategories.isEmpty()) { + + boolean hasAll = + charity.getCategory().stream() + .filter(Objects::nonNull) + .map(c -> c.toLowerCase().trim()) + .collect(java.util.stream.Collectors.toSet()) + .containsAll(selectedCategories); + + if (!hasAll) { + continue; + } + } + + filtered.add(charity); + } + + return filtered; + } + + /** + * This method is used to display the charities in the cards container. + * + * @param charities is the list of charities to be displayed. + */ + private void displayCharities(List charities) { + cardsContainer.getChildren().clear(); + + for (Charity charity : charities) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/organizationCard.fxml")); + Parent card = loader.load(); + OrganizationCardController cardController = loader.getController(); + cardController.setOrganization(charity); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/GiveFeedbackController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/GiveFeedbackController.java new file mode 100644 index 00000000..32a05ce4 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/GiveFeedbackController.java @@ -0,0 +1,110 @@ +package ntnu.systemutvikling.team6.controller; + +import java.io.IOException; +import java.util.ArrayList; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.layout.FlowPane; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.FeedbackDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Feedback; + +public class GiveFeedbackController extends BaseController { + private Charity charity; + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + @FXML private FlowPane feedbackContainer; + @FXML private Label charityNameLabel; + @FXML private TextArea feedbackCommentArea; + + @FXML + public void setCharity(Charity charity) { + this.charity = charity; + + charityNameLabel.setText(charity.getName()); + } + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + populateFields(); + } + + private void populateFields() { + DatabaseConnection conn = new DatabaseConnection(); + FeedbackDAO feedbackDAO = new FeedbackDAO(conn); + ArrayList feedbacks = + feedbackDAO.getFeedbackforCharityUUID(charity.getUUID().toString()); + displayFeedbacks(feedbacks); + } + + private void displayFeedbacks(ArrayList feedbacks) { + feedbackContainer.getChildren().clear(); + if (feedbacks.isEmpty()) { + javafx.scene.control.Label empty = new javafx.scene.control.Label("You have no Feedbacks"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + feedbackContainer.getChildren().add(empty); + } + + for (Feedback feedback : feedbacks) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/feedbackCard.fxml")); + Parent card = loader.load(); + FeedbackCardController cardController = loader.getController(); + cardController.setMessage(feedback); + cardController.setAuthToken(authToken); + feedbackContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + @FXML + private void handleSubmitFeedback(ActionEvent event) { + String feedbackCommentAreaText = feedbackCommentArea.getText(); + Feedback newFeedback = new Feedback(authToken.getCurrentUser(), feedbackCommentAreaText); + + DatabaseConnection conn = new DatabaseConnection(); + FeedbackDAO feedbackDAO = new FeedbackDAO(conn); + boolean submitSuccess; + try { + submitSuccess = feedbackDAO.addFeedbackToCharity(newFeedback, charity); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (submitSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Feedback received", + charity.getName() + " has gotten your feedback"); + LoaderScene.LoadScene("charityPage", event, charity, null, authToken); + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoaderScene.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoaderScene.java deleted file mode 100644 index 83ace1ea..00000000 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoaderScene.java +++ /dev/null @@ -1,63 +0,0 @@ -package ntnu.systemutvikling.team6.controller; - -import java.io.IOException; -import java.util.Objects; -import javafx.event.ActionEvent; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.image.Image; -import javafx.stage.Stage; -import ntnu.systemutvikling.team6.HmHApplication; -import ntnu.systemutvikling.team6.models.Charity; - -/** - * This class is a utility class that is used to load different scenes in the application. For now, - * It is used to switch between the front page, charity page, and donation page. It takes care of - * loading the FXML file, setting the controller, and switching the scene. - */ -public class LoaderScene { - /** - * When going to a new scene, this method is called to load the new scene. It takes the name of - * the scene to load, the event that triggered the scene change, and the charity that is being - * passed to the new scene (if applicable). It loads the FXML file for the new scene, sets the - * controller, and switches the scene. - * - * @param sceneName - * @param event - * @param charity - */ - public static void LoadScene(String sceneName, ActionEvent event, Charity charity) { - try { - System.out.println(HmHApplication.class.getResource("/fxml/" + sceneName + ".fxml")); - FXMLLoader fxmlLoader = - new FXMLLoader(HmHApplication.class.getResource("/fxml/" + sceneName + ".fxml")); - Parent root = fxmlLoader.load(); - - System.out.println("Controller: " + fxmlLoader.getController()); - Object controller = fxmlLoader.getController(); - - // Needs to be expanded when more pages get implemented. - if (controller instanceof CharityPageController charityController) { - charityController.setCharity(charity); - } - if (controller instanceof DonationPageController donationController) { - donationController.setCharity(charity); - } - - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Image icon = - new Image( - Objects.requireNonNull(HmHApplication.class.getResource("/images/Logo.png")) - .openStream()); - stage.getIcons().add(icon); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.setFullScreen(true); - stage.show(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoginPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoginPageController.java new file mode 100644 index 00000000..99633dac --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/LoginPageController.java @@ -0,0 +1,71 @@ +package ntnu.systemutvikling.team6.controller; + +import java.awt.*; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.FooterController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; + +public class LoginPageController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FooterController footerController; + + @FXML private TextField emailField; + @FXML private PasswordField passwordField; + + @Override + protected void authTokenisSet() { + if (isLoggedin()) { + LoaderScene.LoadScene("frontPage", new ActionEvent(), null, null, authToken); + } + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } + + @FXML + private void handleLogin(ActionEvent event) { + String emailText = emailField.getText(); + String password = passwordField.getText(); + + if (emailText.isBlank() || password.isBlank()) { + showAlert(Alert.AlertType.ERROR, "Empty input", "Please fill out all fields"); + return; + } + + if (!emailText.contains("@") || !emailText.contains(".")) { + showAlert(Alert.AlertType.ERROR, "Invalid Email", "Please enter a valid email"); + return; + } + + boolean loginSuccess; + try { + loginSuccess = authToken.login(emailText, password); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (loginSuccess) { + showAlert(Alert.AlertType.INFORMATION, "Login Success", "Login Successful!"); + LoaderScene.LoadScene("profile_user_Settings", event, null, null, authToken); + } else { + showAlert( + Alert.AlertType.ERROR, + "Account not found", + "User logg inn failed. Either email is wrong or password"); + emailField.setText(""); + passwordField.setText(""); + } + } + + @FXML + private void switchToSignupPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("creater_user_site", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/BaseController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/BaseController.java new file mode 100644 index 00000000..2b9a8121 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/BaseController.java @@ -0,0 +1,56 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.scene.control.Alert; +import ntnu.systemutvikling.team6.service.AuthenticationService; + +public abstract class BaseController { + protected AuthenticationService authToken; + + public void setAuthToken(AuthenticationService authToken) { + this.authToken = authToken; + authTokenisSet(); + } + ; + + protected abstract void authTokenisSet(); + + // Update ui (login button or profile circle) after authtoken is set: + // Make sure to invoke navbarController.setAuthtoken AND FooterController on controller that have + // @FXML private navbarController as an attribute. + // If footerController and NavbarController on the same file overwrite one of the controllers + // switchtofrontpage. + + protected boolean isLoggedin() { + return authToken != null && authToken.isLoggedin(); + } + + /** + * Show an JavaFx alert dialog with the specified type, title, and message. + * + * @param type + * @param title + * @param message + */ + protected void showAlert(Alert.AlertType type, String title, String message) { + Alert alert = new Alert(type); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + + // Example on the minimum inside of a controller that extends the baseControlle and inserts footer + // and navbar fxml: + /* + @FXML + private NavbarController navbarController; + @FXML private FooterController footerController; + + @Override + protected void authTokenisSet() { + navbarController.setAuthToken(authToken); + footerController.setAuthToken(authToken); + } + */ + +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/CategoryTagController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/CategoryTagController.java new file mode 100644 index 00000000..1a4540a0 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/CategoryTagController.java @@ -0,0 +1,43 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; + +public class CategoryTagController extends BaseController { + @FXML private Button button; + private static final String[][] TAG_COLORS = { + {"#E5F0D7", "#6E8A5C"}, // green + {"#D7E8F0", "#5C7A8A"}, // blue + {"#F0E5D7", "#8A6E5C"}, // orange + {"#EFD7F0", "#8A5C8A"}, // purple + {"#F0D7D7", "#8A5C5C"}, // red + {"#D7F0EE", "#5C8A87"}, // teal + {"#F0EDD7", "#8A845C"}, // yellow + }; + + private String[] getRandomTagColor() { + return TAG_COLORS[(int) (Math.random() * TAG_COLORS.length)]; + } + + private String category; + + @Override + protected void authTokenisSet() {} + + public void setCategory(String category) { + this.category = category; + + button.setText(category); + String[] colors = getRandomTagColor(); + button.setStyle( + "-fx-background-color: " + + colors[0] + + ";" + + "-fx-text-fill: " + + colors[1] + + ";" + + "-fx-background-radius: 20;" + + "-fx-font-size: 11px;" + + "-fx-padding: 4 10 4 10;"); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/DonationCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/DonationCardController.java new file mode 100644 index 00000000..34caf904 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/DonationCardController.java @@ -0,0 +1,28 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import ntnu.systemutvikling.team6.models.Donation; + +public class DonationCardController extends BaseController { + @FXML private Label charityNameLabel; + @FXML private Label purchaseIDLabel; + @FXML private Label dateLabel; + @FXML private Label AnonymousLabel; + @FXML private Label totalLabel; + + private Donation donation; + + @Override + protected void authTokenisSet() {} + + public void setDonation(Donation donation) { + this.donation = donation; + + charityNameLabel.setText(donation.getCharity().getName()); + purchaseIDLabel.setText(donation.getDonationID().toString()); + dateLabel.setText(donation.getDate().toString()); + AnonymousLabel.setText(donation.isAnonymous() ? "Yes" : "No"); + totalLabel.setText(String.valueOf(donation.getAmount())); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FeedbackCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FeedbackCardController.java new file mode 100644 index 00000000..17bb8f31 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FeedbackCardController.java @@ -0,0 +1,26 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import ntnu.systemutvikling.team6.models.Feedback; + +public class FeedbackCardController extends BaseController { + @FXML private Label usernameLabel; + @FXML private Label dateLabel; + @FXML private Label commentLabel; + + private Feedback feedback; + + @Override + protected void authTokenisSet() {} + + public void setMessage(Feedback feedback) { + this.feedback = feedback; + + System.out.println(feedback.isAnonymous()); + usernameLabel.setText( + feedback.isAnonymous() ? "Anonymous Doner" : feedback.getUser().getUsername()); + dateLabel.setText(feedback.getDate().toString()); + commentLabel.setText(feedback.getComment()); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FooterController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FooterController.java new file mode 100644 index 00000000..c6e800b8 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/FooterController.java @@ -0,0 +1,21 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.event.ActionEvent; +import javafx.fxml.FXML; + +public class FooterController extends BaseController { + @FXML + private void switchToAboutPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("aboutPage", event, null, null, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("frontPage", event, null, null, authToken); + } + + @Override + protected void authTokenisSet() {} +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InboxCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InboxCardController.java new file mode 100644 index 00000000..d26e9d77 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InboxCardController.java @@ -0,0 +1,26 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import ntnu.systemutvikling.team6.models.user.Message; + +public class InboxCardController extends BaseController { + @FXML private Label messageFrom; + @FXML private Label messageTitle; + @FXML private Label messageContent; + @FXML private Label messageDate; + + private Message message; + + @Override + protected void authTokenisSet() {} + + public void setMessage(Message message) { + this.message = message; + + messageFrom.setText(message.getFrom().getName()); + messageTitle.setText(message.getTitle()); + messageContent.setText(message.getContent()); + messageDate.setText(message.getTimeAndDate().toString()); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InterestCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InterestCardController.java new file mode 100644 index 00000000..73dc1e5b --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/InterestCardController.java @@ -0,0 +1,49 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import ntnu.systemutvikling.team6.models.Charity; + +public class InterestCardController extends BaseController { + @FXML private Label charityDescription; + @FXML private Label verifyLabel; + @FXML private Label charityNameLabel; + + @FXML private Button detailsButton; + @FXML private Button donateButton; + + private Charity charity; + + @Override + protected void authTokenisSet() {} + + public void setOrganization(Charity charity) { + this.charity = charity; + + charityNameLabel.setText(charity.getName()); + verifyLabel.setText(charity.getPreApproved() ? "Verify" : "Unverified"); + verifyLabel.setStyle( + charity.getPreApproved() + ? "-fx-background-color: #2f8f3a; -fx-alignment: CENTER_LEFT; -fx-text-fill: white;" + : "-fx-alignment: CENTER_LEFT; -fx-background-color: #D11D27; -fx-text-fill: white;"); + charityDescription.setText(charity.getDescription()); + + if (charity.getName().equals("You have no Favourites")) { + detailsButton.setVisible(false); + donateButton.setVisible(false); + } + } + + /* EVENTS */ + @FXML + private void switchToCharity(ActionEvent event) { + LoaderScene.LoadScene("CharityPage", event, charity, null, authToken); + } + + @FXML + private void switchToDonate(ActionEvent event) { + LoaderScene.LoadScene("DonationPage", event, charity, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/LoaderScene.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/LoaderScene.java new file mode 100644 index 00000000..173c394b --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/LoaderScene.java @@ -0,0 +1,108 @@ +package ntnu.systemutvikling.team6.controller.components; + +import java.io.IOException; +import java.util.Objects; +import javafx.event.ActionEvent; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.image.Image; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.HmHApplication; +import ntnu.systemutvikling.team6.controller.*; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.service.AuthenticationService; + +/** + * This class is a utility class that is used to load different scenes in the application. For now, + * It is used to switch between the front page, charity page, and donation page. It takes care of + * loading the FXML file, setting the controller, and switching the scene. + */ +public class LoaderScene { + /** + * When going to a new scene, this method and another called to load the new scene. It loads the + * FXML file for the new scene, sets the controller, and switches the scene. + * + * @param sceneName + * @param event + * @param charity + */ + public static void LoadScene( + String sceneName, + Stage stage, + Charity charity, + String query, + AuthenticationService authtoken) { + try { + System.out.println(HmHApplication.class.getResource("/fxml/" + sceneName + ".fxml")); + FXMLLoader fxmlLoader = + new FXMLLoader(HmHApplication.class.getResource("/fxml/" + sceneName + ".fxml")); + Parent root = fxmlLoader.load(); + + System.out.println("Controller: " + fxmlLoader.getController()); + Object controller = fxmlLoader.getController(); + + // Needs to be expanded when more pages get implemented. + // Controllers that need charities: + if (charity != null) { + if (controller instanceof CharityPageController charityController) { + charityController.setCharity(charity); + } + if (controller instanceof DonationPageController donationController) { + donationController.setCharity(charity); + } + if (controller instanceof GiveFeedbackController giveFeedbackController) { + giveFeedbackController.setCharity(charity); + } + } + + // Controllers that need query + if (query != null) { + if (controller instanceof AvailableOrganizationController availableOrganizationController) { + availableOrganizationController.setInitialSearch(query); + } + } + + // All controllers need to set authtoken + if (controller instanceof BaseController baseController) { + baseController.setAuthToken(authtoken); + } + + Image icon = + new Image( + Objects.requireNonNull(HmHApplication.class.getResource("/images/Logo.png")) + .openStream()); + stage.getIcons().add(icon); + Scene scene = new Scene(root); + stage.setScene(scene); + stage.setFullScreen(true); + stage.show(); + stage + .iconifiedProperty() + .addListener( + (obs, wasIconified, isNowIconified) -> { + if (!isNowIconified) { + stage.setFullScreen(true); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * This method is the same as above, but tailored for Action Events, say through clicking a + * button. It takes the name of * the scene to load, the event that triggered the scene change, + * and the charity that is being * passed to the new scene (if applicable). + */ + public static void LoadScene( + String sceneName, + ActionEvent event, + Charity charity, + String query, + AuthenticationService authtoken) { + Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); + LoadScene(sceneName, stage, charity, query, authtoken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/NavbarController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/NavbarController.java new file mode 100644 index 00000000..ceca5890 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/NavbarController.java @@ -0,0 +1,73 @@ +package ntnu.systemutvikling.team6.controller.components; + +import java.awt.*; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; + +public class NavbarController extends BaseController { + @FXML protected TextField frontSearchField; + @FXML private Button loginButton; + @FXML private Button profileButton; + @FXML private Button toCharityUserButton; + + @Override + protected void authTokenisSet() { + boolean loggedIn = super.isLoggedin(); + if (loggedIn) { + if (authToken.isCharityUser() != null) { + toCharityUserButton.setVisible(true); + toCharityUserButton.setManaged(true); + } + loginButton.setVisible(false); + loginButton.setManaged(false); + profileButton.setVisible(true); + profileButton.setManaged(true); + profileButton.setText( + authToken.getCurrentUser().getUsername().substring(0, 2).toUpperCase().trim()); + } else { + loginButton.setVisible(true); + loginButton.setManaged(true); + profileButton.setVisible(false); + profileButton.setManaged(false); + toCharityUserButton.setVisible(false); + toCharityUserButton.setManaged(false); + } + } + + @FXML + private void handleFrontSearch(ActionEvent event) { + String query = frontSearchField.getText().trim(); + + if (query.isEmpty()) { + return; + } + + LoaderScene.LoadScene("available_organizations", event, null, query, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("frontPage", event, null, null, authToken); + } + + @FXML + private void switchToProfilePage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } + + @FXML + private void switchToLoginPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("loginSite", event, null, null, authToken); + } + + @FXML + private void switchToCharityUserPage(ActionEvent event) { + System.out.println("Click!"); + LoaderScene.LoadScene("profile_org_settings", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrgDonationCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrgDonationCardController.java new file mode 100644 index 00000000..00b144bb --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrgDonationCardController.java @@ -0,0 +1,27 @@ +package ntnu.systemutvikling.team6.controller.components; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import ntnu.systemutvikling.team6.models.Donation; + +public class OrgDonationCardController extends BaseController { + @FXML private Label donerNameLabel; + @FXML private Label purchaseIDLabel; + @FXML private Label dateLabel; + @FXML private Label totalLabel; + + private Donation donation; + + @Override + protected void authTokenisSet() {} + + public void setDonation(Donation donation) { + this.donation = donation; + + donerNameLabel.setText( + donation.isAnonymous() ? "Anonymous Doner" : donation.getCharity().getName()); + purchaseIDLabel.setText(donation.getDonationID().toString()); + dateLabel.setText(donation.getDate().toString()); + totalLabel.setText(String.valueOf(donation.getAmount())); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/OrganizationCardController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.java similarity index 69% rename from helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/OrganizationCardController.java rename to helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.java index b51e530e..24a7c520 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/OrganizationCardController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/components/OrganizationCardController.java @@ -1,4 +1,4 @@ -package ntnu.systemutvikling.team6.controller; +package ntnu.systemutvikling.team6.controller.components; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -10,7 +10,7 @@ * looped upon in FronpageController. It is used to display the name and description of a charity, * and to switch to the charity page or donation page when the user clicks on the card. */ -public class OrganizationCardController { +public class OrganizationCardController extends BaseController { @FXML private Label organizationName; @@ -18,6 +18,9 @@ public class OrganizationCardController { private Charity charity; + @Override + protected void authTokenisSet() {} + public void setOrganization(Charity charity) { this.charity = charity; @@ -27,10 +30,11 @@ public void setOrganization(Charity charity) { /* EVENTS */ public void switchToCharityPage(ActionEvent event) { - LoaderScene.LoadScene("CharityPage", event, charity); + LoaderScene.LoadScene("CharityPage", event, charity, null, authToken); } public void switchToDonationPage(ActionEvent event) { - LoaderScene.LoadScene("DonationPage", event, charity); + System.out.println(authToken.getCurrentUser().getId().toString()); + LoaderScene.LoadScene("DonationPage", event, charity, null, authToken); } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgEditController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgEditController.java new file mode 100644 index 00000000..1828c3c6 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgEditController.java @@ -0,0 +1,122 @@ +package ntnu.systemutvikling.team6.controller.profileCharity; + +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; +import ntnu.systemutvikling.team6.database.DAO.CharityUserDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; + +public class profileOrgEditController extends BaseController { + @FXML private NavbarController navbarController; + + @FXML private Label charityNameLabel; + @FXML private Label charityNameLabel2; + @FXML private TextArea descriptionField; + + @Override + protected void authTokenisSet() { + if (!isLoggedin() || authToken.isCharityUser() == null) { + showAlert( + Alert.AlertType.ERROR, + "Not logged inn or dont have privileges", + "You need to be logged inn an account with Charity User priviliges."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + return; + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + private void populateFields() { + Charity usersCharity = authToken.isCharityUser(); + charityNameLabel.setText(usersCharity.getName()); + charityNameLabel2.setText(usersCharity.getName()); + descriptionField.setText(usersCharity.getDescription()); + } + + @FXML + private void handleSaveDescription(ActionEvent event) { + String descriptionFieldText = descriptionField.getText(); + + if (descriptionFieldText.isBlank()) { + showAlert( + Alert.AlertType.ERROR, + "Empty input", + "Yeah, maybe it was empty before but now it need one"); + return; + } + + boolean updateSuccess; + DatabaseConnection conn = new DatabaseConnection(); + CharityUserDAO userDataObject = new CharityUserDAO(conn); + Charity savedCharity = authToken.isCharityUser(); + Charity minimalCharityWithJustNewDescription = + new Charity( + savedCharity.getUUID().toString(), + savedCharity.getOrg_number(), + savedCharity.getName(), + null, + savedCharity.getStatus(), + savedCharity.getPreApproved(), + descriptionFieldText, + null, + null, + null); + try { + updateSuccess = + userDataObject.updateCharityVanityDescription(minimalCharityWithJustNewDescription); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (updateSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Settings updated", + "You have successfully changed your settings"); + authToken.isCharityUser().setDescription(descriptionFieldText); + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } else { + System.out.println("Something went wrong when updating Settings"); + } + } + + @FXML + private void switchToPaymentsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Payments", event, null, null, authToken); + } + + @FXML + private void switchToFeedbackPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Inbox", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Settings", event, null, null, authToken); + } + + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgInboxController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgInboxController.java new file mode 100644 index 00000000..c0dd5db6 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgInboxController.java @@ -0,0 +1,131 @@ +package ntnu.systemutvikling.team6.controller.profileCharity; + +import java.io.IOException; +import java.util.ArrayList; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.layout.FlowPane; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.FeedbackDAO; +import ntnu.systemutvikling.team6.database.DAO.MessageDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Feedback; +import ntnu.systemutvikling.team6.models.user.Message; + +public class profileOrgInboxController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FlowPane cardsContainer; + @FXML private Label charityNameLabel; + @FXML private TextField messageTitleField; + @FXML private TextArea messageContentField; + + @Override + protected void authTokenisSet() { + if (!isLoggedin() || authToken.isCharityUser() == null) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + Charity usersCharity = authToken.isCharityUser(); + charityNameLabel.setText(usersCharity.getName()); + + // Messages + DatabaseConnection conn = new DatabaseConnection(); + FeedbackDAO feedbackDAO = new FeedbackDAO(conn); + ArrayList feedbacks = + feedbackDAO.getFeedbackforCharityUUID(authToken.isCharityUser().getUUID().toString()); + displayFeedbacks(feedbacks); + } + + private void displayFeedbacks(ArrayList feedbacks) { + cardsContainer.getChildren().clear(); + if (feedbacks.isEmpty()) { + Label empty = new Label("You have no Feedbacks"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + cardsContainer.getChildren().add(empty); + } + + for (Feedback feedback : feedbacks) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/feedbackCard.fxml")); + Parent card = loader.load(); + FeedbackCardController cardController = loader.getController(); + cardController.setMessage(feedback); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + @FXML + private void handleSendMessage(ActionEvent event) { + String title = messageTitleField.getText().trim(); + String content = messageContentField.getText().trim(); + + if (title.isBlank() || content.isBlank()) { + showAlert(Alert.AlertType.ERROR, "Empty fields", "Please fill in both title and message."); + return; + } + + try { + DatabaseConnection conn = new DatabaseConnection(); + MessageDAO messageDAO = new MessageDAO(conn); + Charity charity = authToken.isCharityUser(); + Message messageStaticId = new Message(title, authToken.isCharityUser(), content); + messageDAO.addMessage(messageStaticId); + showAlert(Alert.AlertType.INFORMATION, "Sent!", "Your message has been sent to all donors."); + messageTitleField.clear(); + messageContentField.clear(); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Error", "Something went wrong sending the message."); + } + } + + // Sidebar Methods + @FXML + private void switchToPaymentsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Payments", event, null, null, authToken); + } + + @FXML + private void switchToEditPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_edit", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Settings", event, null, null, authToken); + } + + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgPaymentsController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgPaymentsController.java new file mode 100644 index 00000000..32c2b26d --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgPaymentsController.java @@ -0,0 +1,102 @@ +package ntnu.systemutvikling.team6.controller.profileCharity; + +import java.io.IOException; +import java.util.List; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.DonationDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Donation; +import ntnu.systemutvikling.team6.models.registry.DonationRegistry; + +public class profileOrgPaymentsController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private VBox cardsContainer; + @FXML private Label charityNameLabel; + + @Override + protected void authTokenisSet() { + if (!isLoggedin() || authToken.isCharityUser() == null) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + Charity usersCharity = authToken.isCharityUser(); + charityNameLabel.setText(usersCharity.getName()); + + // DonationHistory + DatabaseConnection conn = new DatabaseConnection(); + DonationDAO donationDAO = new DonationDAO(conn); + DonationRegistry donationRegistry = + donationDAO.getDonationForCharity(authToken.isCharityUser().getUUID().toString()); + displayDonations(donationRegistry); + } + + private void displayDonations(DonationRegistry donationRegistry) { + cardsContainer.getChildren().clear(); + List donations = donationRegistry.getAllDonations(); + if (donations.isEmpty()) { + Label empty = new Label("You have no Donations"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + cardsContainer.getChildren().add(empty); + } + + for (Donation donation : donations) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/profileOrgDonationCard.fxml")); + Parent card = loader.load(); + OrgDonationCardController cardController = loader.getController(); + cardController.setDonation(donation); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + // Sidebar Methods + @FXML + private void switchToEditPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_edit", event, null, null, authToken); + } + + @FXML + private void switchToFeedbackPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Inbox", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Settings", event, null, null, authToken); + } + + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgSettingsController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgSettingsController.java new file mode 100644 index 00000000..c8c3824c --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileCharity/profileOrgSettingsController.java @@ -0,0 +1,147 @@ +package ntnu.systemutvikling.team6.controller.profileCharity; + +import java.io.IOException; +import java.util.List; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.CharityUserDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; + +public class profileOrgSettingsController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private Label charityNameLabel; + @FXML private TextField organizationNameField; + @FXML private HBox tagContainer; + + @Override + protected void authTokenisSet() { + if (!isLoggedin() || authToken.isCharityUser() == null) { + showAlert( + Alert.AlertType.ERROR, + "Not logged inn or dont have privileges", + "You need to be logged inn an account with Charity User priviliges."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + return; + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + private void populateFields() { + Charity usersCharity = authToken.isCharityUser(); + charityNameLabel.setText(usersCharity.getName()); + organizationNameField.setText(usersCharity.getName()); + + // Tags + List categories = usersCharity.getCategory(); + displayCategories(categories); + } + + private void displayCategories(List categories) { + tagContainer.getChildren().clear(); + if (categories.isEmpty()) { + Label empty = new Label("No categories"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + tagContainer.getChildren().add(empty); + return; + } + + for (String category : categories) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/categoryTag.fxml")); + Parent card = loader.load(); + CategoryTagController cardController = loader.getController(); + cardController.setCategory(category); + cardController.setAuthToken(authToken); + tagContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + @FXML + private void handleNewName(ActionEvent event) { + String organizationNameFieldText = organizationNameField.getText(); + + if (organizationNameFieldText.isBlank()) { + showAlert(Alert.AlertType.ERROR, "Empty input", "Please fill out all fields"); + return; + } + + boolean updateSuccess; + DatabaseConnection conn = new DatabaseConnection(); + CharityUserDAO userDataObject = new CharityUserDAO(conn); + Charity savedCharity = authToken.isCharityUser(); + Charity minimalCharityWithJustNewName = + new Charity( + savedCharity.getUUID().toString(), + savedCharity.getOrg_number(), + organizationNameFieldText, + null, + savedCharity.getStatus(), + savedCharity.getPreApproved(), + null, + null, + null, + null); + try { + updateSuccess = userDataObject.updateCharityVanityName(minimalCharityWithJustNewName); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (updateSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Settings updated", + "You have successfully changed your settings"); + authToken.isCharityUser().setName(organizationNameFieldText); + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } else { + System.out.println("Something went wrong when updating Settings"); + } + } + + @FXML + private void switchToPaymentsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Payments", event, null, null, authToken); + } + + @FXML + private void switchToFeedbackPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_Inbox", event, null, null, authToken); + } + + @FXML + private void switchToEditPage(ActionEvent event) { + LoaderScene.LoadScene("profile_org_edit", event, null, null, authToken); + } + + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserHistoryController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserHistoryController.java new file mode 100644 index 00000000..9756867d --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserHistoryController.java @@ -0,0 +1,114 @@ +package ntnu.systemutvikling.team6.controller.profileUser; + +import java.io.IOException; +import java.util.List; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.DonationDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Donation; +import ntnu.systemutvikling.team6.models.registry.DonationRegistry; +import ntnu.systemutvikling.team6.models.user.User; + +public class profileUserHistoryController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private VBox cardsContainer; + @FXML private Label nameLabel; + @FXML private Label shortNameLabel; + @FXML private Label totalAmmount; + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + User user = authToken.getCurrentUser(); + // Names + nameLabel.setText(user.getUsername()); + shortNameLabel.setText(user.getUsername().substring(0, 2).toUpperCase().trim()); + + // DonationHistory + DatabaseConnection conn = new DatabaseConnection(); + DonationDAO donationDAO = new DonationDAO(conn); + DonationRegistry donationRegistry = + donationDAO.getDonationForUser(authToken.getCurrentUser().getId().toString()); + double ammount = + donationRegistry.getAllDonations().stream().mapToDouble(d -> d.getAmount()).sum(); + totalAmmount.setText(String.valueOf(ammount)); + displayDonations(donationRegistry); + } + + private void displayDonations(DonationRegistry donationRegistry) { + cardsContainer.getChildren().clear(); + List donations = donationRegistry.getAllDonations(); + if (donations.isEmpty()) { + Label empty = new Label("You have no Donations"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + cardsContainer.getChildren().add(empty); + } + + for (Donation donation : donations) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/profileDonationCard.fxml")); + Parent card = loader.load(); + DonationCardController cardController = loader.getController(); + cardController.setDonation(donation); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + // Sidebar Methods + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToInterestPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_interests", event, null, null, authToken); + } + + @FXML + private void switchToInboxPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_inbox", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInboxController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInboxController.java new file mode 100644 index 00000000..0292d387 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInboxController.java @@ -0,0 +1,105 @@ +package ntnu.systemutvikling.team6.controller.profileUser; + +import java.io.IOException; +import java.util.List; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.layout.FlowPane; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.models.user.Inbox; +import ntnu.systemutvikling.team6.models.user.Message; +import ntnu.systemutvikling.team6.models.user.User; + +public class profileUserInboxController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FlowPane cardsContainer; + @FXML private Label nameLabel; + @FXML private Label shortNameLabel; + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + User user = authToken.getCurrentUser(); + // Names + nameLabel.setText(user.getUsername()); + shortNameLabel.setText(user.getUsername().substring(0, 2).toUpperCase().trim()); + + // Messages + Inbox inbox = authToken.getCurrentUser().getInbox(); + displayInbox(inbox); + } + + private void displayInbox(Inbox inbox) { + cardsContainer.getChildren().clear(); + List messages = inbox.getMessages(); + if (messages.isEmpty()) { + Label empty = new Label("You have no messages"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + cardsContainer.getChildren().add(empty); + } + + for (Message message : messages) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/inboxCard.fxml")); + Parent card = loader.load(); + InboxCardController cardController = loader.getController(); + cardController.setMessage(message); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + // Sidebar Methods + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToInterestPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_interests", event, null, null, authToken); + } + + @FXML + private void switchToHistoryPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_history", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInterestController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInterestController.java new file mode 100644 index 00000000..00c1f131 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserInterestController.java @@ -0,0 +1,111 @@ +package ntnu.systemutvikling.team6.controller.profileUser; + +import java.io.IOException; +import java.util.ArrayList; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.layout.FlowPane; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.*; +import ntnu.systemutvikling.team6.database.DAO.FavouritesDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.user.Settings; +import ntnu.systemutvikling.team6.models.user.User; + +public class profileUserInterestController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private FlowPane cardsContainer; + @FXML private Label nameLabel; + @FXML private Label shortNameLabel; + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + User user = authToken.getCurrentUser(); + Settings settings = user.getSettings(); + // Names + nameLabel.setText(user.getUsername()); + shortNameLabel.setText(user.getUsername().substring(0, 2).toUpperCase().trim()); + + // Favourites + DatabaseConnection conn = new DatabaseConnection(); + FavouritesDAO favouritesDAO = new FavouritesDAO(conn); + ArrayList favourites = + new ArrayList<>( + favouritesDAO.getFavouritesForUser(authToken.getCurrentUser().getId().toString())); + displayFavourites(favourites); + } + + private void displayFavourites(ArrayList favourites) { + cardsContainer.getChildren().clear(); + if (favourites.isEmpty()) { + Label empty = new Label("You have no favourited Charities"); + empty.setStyle("-fx-text-fill: #777777; -fx-font-size: 14;"); + cardsContainer.getChildren().add(empty); + } + + for (Charity charity : favourites) { + try { + FXMLLoader loader = + new FXMLLoader(getClass().getResource("/fxml/components/interestCard.fxml")); + Parent card = loader.load(); + InterestCardController cardController = loader.getController(); + cardController.setOrganization(charity); + cardController.setAuthToken(authToken); + cardsContainer.getChildren().add(card); + } catch (IOException e) { + throw new RuntimeException("Could not load organization card.", e); + } + } + } + + // Sidebar Methods + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToInboxPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_inbox", event, null, null, authToken); + } + + @FXML + private void switchToHistoryPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_history", event, null, null, authToken); + } + + @FXML + private void switchToSettingsPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserSettingsController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserSettingsController.java new file mode 100644 index 00000000..7e92fea7 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/profileUser/profileUserSettingsController.java @@ -0,0 +1,229 @@ +package ntnu.systemutvikling.team6.controller.profileUser; + +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.stage.Stage; +import ntnu.systemutvikling.team6.controller.components.BaseController; +import ntnu.systemutvikling.team6.controller.components.LoaderScene; +import ntnu.systemutvikling.team6.controller.components.NavbarController; +import ntnu.systemutvikling.team6.database.DAO.UserDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.user.*; +import ntnu.systemutvikling.team6.security.PasswordHasher; + +public class profileUserSettingsController extends BaseController { + @FXML private NavbarController navbarController; + @FXML private ComboBox languageComboBox; + @FXML private ComboBox themeComboBox; + @FXML private ToggleButton anonymousToggle; + @FXML private Label anonymousLabel; + + @FXML private TextField NameField; + @FXML private TextField EmailField; + @FXML private PasswordField PassWordField; + @FXML private TextField ConfirmPasswordField; + @FXML private Button ConfirmChangeSettings; + @FXML private Button ConfirmChangeSettings1; + + // Sidebar FXML variables + @FXML private Label nameLabel; + @FXML private Label shortNameLabel; + @FXML private Label shortNameLabel2; + @FXML private Button logoutButton; + + @Override + protected void authTokenisSet() { + if (!isLoggedin()) { + showAlert(Alert.AlertType.ERROR, "Not logged inn", "You need to be logged inn to donate."); + Platform.runLater( + () -> { + Stage stage = + (Stage) + Stage.getWindows().stream().filter(w -> w.isShowing()).findFirst().orElse(null); + if (stage != null) { + LoaderScene.LoadScene("loginSite", stage, null, null, authToken); + } + }); + } + navbarController.setAuthToken(authToken); + populateFields(); + } + + public void populateFields() { + languageComboBox.getItems().addAll("English", "Norwegian"); + themeComboBox.getItems().addAll("Light mode", "Dark mode"); + + User user = authToken.getCurrentUser(); + Settings settings = user.getSettings(); + // Names + nameLabel.setText(user.getUsername()); + shortNameLabel.setText(user.getUsername().substring(0, 2).toUpperCase().trim()); + shortNameLabel2.setText(user.getUsername().substring(0, 2).toUpperCase().trim()); + + NameField.setText(user.getUsername()); + EmailField.setText(user.getEmail()); + + // SettingsPage Spesefic: + languageComboBox.setValue( + settings.getLanguage() == Language.NORWEGIAN ? "Norwegian" : "English"); + themeComboBox.setValue(settings.isLightMode() ? "Light mode" : "Dark mode"); + anonymousToggle.setSelected(settings.isAnonymous()); + + boolean on = settings.isAnonymous(); + anonymousLabel.setText(on ? "On" : "Off"); + anonymousToggle.setStyle( + "-fx-background-color: " + + (on ? "#2f8f8b" : "#ccc") + + ";" + + "-fx-background-radius: 14; -fx-min-width: 32; -fx-min-height: 28;" + + "-fx-max-width: 52; -fx-max-height: 28;"); + } + + @FXML + private void handleAnonymousToggle(ActionEvent event) { + boolean on = anonymousToggle.isSelected(); + anonymousLabel.setText(on ? "On" : "Off"); + anonymousToggle.setStyle( + "-fx-background-color: " + + (on ? "#2f8f8b" : "#ccc") + + ";" + + "-fx-background-radius: 14; -fx-min-width: 32; -fx-min-height: 28;" + + "-fx-max-width: 52; -fx-max-height: 28;"); + } + + @FXML + private void handleNewProfile(ActionEvent event) { + String nameText = NameField.getText(); + String emailText = EmailField.getText(); + String password = PassWordField.getText(); + String confirmPassword = ConfirmPasswordField.getText(); + + if (nameText.isBlank() + || emailText.isBlank() + || password.isBlank() + || confirmPassword.isBlank()) { + showAlert(Alert.AlertType.ERROR, "Empty input", "Please fill out all fields"); + return; + } + + if (emailText == null + || emailText.isBlank() + || !emailText.contains("@") + || !emailText.contains(".")) { + showAlert(Alert.AlertType.ERROR, "Invalid Email", "Please enter a valid email"); + return; + } + + if (!password.equals(confirmPassword)) { + showAlert(Alert.AlertType.ERROR, "Mismatch of password", "Password do not match"); + return; + } + String hashPassword = new PasswordHasher().getHashPassword(password); + User newUserOnlyCredentials = + new User( + authToken.getCurrentUser().getId().toString(), + nameText, + emailText, + hashPassword, + "NORMAL_USER"); + + boolean updateSuccess; + DatabaseConnection conn = new DatabaseConnection(); + UserDAO userDataObject = new UserDAO(conn); + try { + if (!emailText.equals(authToken.getCurrentUser().getEmail())) { + boolean isEmailTaken = userDataObject.isEmailTaken(emailText); + if (!isEmailTaken) { + updateSuccess = userDataObject.updateUserDetails(newUserOnlyCredentials); + } else { + throw new IllegalArgumentException("Email Alreay taken"); + } + } else { + updateSuccess = userDataObject.updateUserDetails(newUserOnlyCredentials); + } + } catch (IllegalArgumentException e) { + showAlert( + Alert.AlertType.ERROR, "Email already taken", "Email already taken by another user."); + return; + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (updateSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Settings updated", + "You have successfully changed your settings"); + authToken.getCurrentUser().setUsername(nameText); + authToken.getCurrentUser().setPassword(password); + authToken.getCurrentUser().setEmail(emailText); + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } else { + System.out.println("Something went wrong when updating Settings"); + } + } + + @FXML + private void handleNewPreferences(ActionEvent event) { + String selectedLanguage = languageComboBox.getValue(); + String selectedTheme = themeComboBox.getValue(); + boolean isAnonymous = anonymousToggle.isSelected(); + + Settings updatedSettings = + new Settings( + isAnonymous, + selectedLanguage.equals("Norwegian") ? Language.NORWEGIAN : Language.ENGLISH, + selectedTheme.equals("Light mode")); + + DatabaseConnection conn = new DatabaseConnection(); + UserDAO userDataObject = new UserDAO(conn); + boolean updateSettingsSuccess; + try { + updateSettingsSuccess = + userDataObject.updateUserSettings(authToken.getCurrentUser(), updatedSettings); + } catch (Exception e) { + e.printStackTrace(); + showAlert(Alert.AlertType.ERROR, "Unexpected Error", "Unexpected error ocurred"); + return; + } + if (updateSettingsSuccess) { + showAlert( + Alert.AlertType.INFORMATION, + "Settings updated", + "You have successfully changed your settings"); + authToken.getCurrentUser().setSettings(updatedSettings); + LoaderScene.LoadScene("profile_user_settings", event, null, null, authToken); + } + } + + // Sidebar Methods + @FXML + private void handleLogout(ActionEvent event) { + authToken.logout(); + showAlert(Alert.AlertType.INFORMATION, "Logging out", "Logging out..."); + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToFrontPage(ActionEvent event) { + LoaderScene.LoadScene("FrontPage", event, null, null, authToken); + } + + @FXML + private void switchToInboxPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_inbox", event, null, null, authToken); + } + + @FXML + private void switchToHistoryPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_history", event, null, null, authToken); + } + + @FXML + private void switchToInterestPage(ActionEvent event) { + LoaderScene.LoadScene("profile_user_interests", event, null, null, authToken); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CategoryDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CategoryDAO.java new file mode 100644 index 00000000..bcc16bab --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CategoryDAO.java @@ -0,0 +1,52 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import ntnu.systemutvikling.team6.database.DatabaseConnection; + +/** + * Data access class responsible for getting all the distinct categories from the database. + * + *

    All queries are executed against a MySQL database via a {@link DatabaseConnection}. + */ +public class CategoryDAO { + private final DatabaseConnection connection; + + /** + * Constructs a new {@code CategoryDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public CategoryDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Retrieves all the categories listed in the Category table of the database. + * + * @return a list of strings containing the name of the categories + */ + public List getCategoriesFromDB() { + List categories = new ArrayList<>(); + + try (Connection conn = connection.getMySqlConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT category FROM Categories")) { + + while (rs.next()) { + categories.add(rs.getString("category")); + } + + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException( + "ERROR: Something went wrong during fetching categories from database."); + } + return categories; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityDAO.java new file mode 100644 index 00000000..85393a8a --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityDAO.java @@ -0,0 +1,214 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.*; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Feedback; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; +import ntnu.systemutvikling.team6.models.user.Language; +import ntnu.systemutvikling.team6.models.user.Settings; +import ntnu.systemutvikling.team6.models.user.User; + +/** + * Data access class responsible for acsessing charity-related data from the database. + * + *

    Primarily provides read methods to retrieve all charities (with their associated feedback and + * users) as well as feedback entries for a specific charity by UUID. + * + *

    All queries are executed against a MySQL database via a {@link DatabaseConnection}. + */ +public class CharityDAO { + private final DatabaseConnection connection; + + /** + * Constructs a new {@code CharitySelect} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public CharityDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Retrieves all charities from the database, including their associated feedback and the users + * who submitted each piece of feedback. + * + *

    The query performs a LEFT JOIN between the {@code Charities}, {@code Feedback}, {@code User} + * and {@code category(s)} tables and a INNER JOIN with {@code CharityVanity} table. Each unique + * charity is added once to the registry; any feedback rows found for that charity are appended to + * its feedback list. + * + *

    Note: charities with no feedback and categories are still included in the result due to the + * LEFT JOIN. + * + * @return a {@link CharityRegistry} containing all charities found in the database, each + * populated with its associated {@link Feedback} objects (if any) + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public CharityRegistry getCharitiesFromDB() { + CharityRegistry registry = null; + Connection conn = null; + + try { + conn = connection.getMySqlConnection(); + + String sql_query = + """ + SELECT + c.UUID_charities, c.org_number, c.pre_approved, c.status, + f.UUID_feedback, f.feedback_comment, f.feedback_date, f.isAnonymous, f.charity_id, f.user_id, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + u.UUID_user, u.user_name, u.user_email, u.user_password, u.role, + cat.category + FROM Charities c + LEFT JOIN Feedback f ON f.charity_id = c.UUID_charities + LEFT JOIN User u ON f.user_id = u.UUID_user + LEFT JOIN Charity_Categories cc ON cc.Charities_UUID_charities = c.UUID_charities + LEFT JOIN Categories cat ON cat.category_id = cc.Categories_category_id + INNER JOIN CharityVanity cv ON cv.UUID_charity = c.UUID_charities + ORDER BY c.UUID_charities; + """; + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql_query); + + Charity currentCharity = null; + String lastCharity = null; + + Set seenFeedbackIds = new HashSet<>(); + + registry = new CharityRegistry(); + + while (rs.next()) { + String currentId = rs.getString("UUID_charities"); + + if (lastCharity == null || !currentId.equals(lastCharity)) { + + currentCharity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + + registry.addCharity(currentCharity); + lastCharity = currentId; + seenFeedbackIds.clear(); + } + + String categoryName = rs.getString("category"); + if (categoryName != null & !currentCharity.getCategory().contains(categoryName)) { + currentCharity.getCategory().add(categoryName); + } + + String feedbackId = rs.getString("UUID_feedback"); + + if (feedbackId != null && !seenFeedbackIds.contains(feedbackId)) { + seenFeedbackIds.add(feedbackId); + + User userWithMinimalSettingsAndInbox = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + + userWithMinimalSettingsAndInbox.setSettings(new Settings(false, Language.ENGLISH, false)); + + Feedback feedback = + new Feedback( + rs.getString("UUID_feedback"), + userWithMinimalSettingsAndInbox, + rs.getString("feedback_comment"), + LocalDate.parse(rs.getString("feedback_date"))); + + currentCharity.getFeedbacks().add(feedback); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + + return registry; + } + + /** + * A helper function that retrieves all feedback entries associated with a specific charity, + * identified by its UUID. Currently, has no use. + * + *

    Each {@link Feedback} object is populated with the associated {@link User} (without settings + * or inbox data). The query uses a LEFT JOIN between the {@code Feedback} and {@code User} + * tables, filtered by {@code charity_id}. + * + * @param charity_uuid the UUID of the charity whose feedback should be retrieved; must not be + * {@code null} + * @return an {@link ArrayList} of {@link Feedback} objects for the given charity; returns an + * empty list if no feedback exists for that charity + * @throws RuntimeException if any exception occurs while executing the query, wrapping the + * original cause + */ + public ArrayList getFeedbackforCharityUUID(String charity_uuid) { + ArrayList Feedbacks = new ArrayList<>(); + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + f.UUID_feedback, f.feedback_comment, f.feedback_date, f.isAnonymous, f.charity_id, f.user_id, + u.UUID_user, u.user_name, u.user_email, u.user_password, u.role, + s.language, s.lightmode + FROM Feedback f + LEFT JOIN User u ON f.user_id = u.UUID_user + RIGHT JOIN Settings s ON u.UUID_user = s.UUID_user + WHERE f.charity_id = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, charity_uuid); + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + User userWithSettingsAndNoInbox = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + userWithSettingsAndNoInbox.setSettings( + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language")), + rs.getBoolean("lightmode"))); + Feedback feedback = + new Feedback( + rs.getString("UUID_feedback"), + userWithSettingsAndNoInbox, + rs.getString("feedback_comment"), + LocalDate.parse(rs.getString("feedback_date"))); + Feedbacks.add(feedback); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + conn = null; + } + return Feedbacks; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityUserDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityUserDAO.java new file mode 100644 index 00000000..8b7fe701 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/CharityUserDAO.java @@ -0,0 +1,161 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; + +/** + * This Data Access Object is responsible for communication to the Database for a potensial user + * that is also a CharityUser. + * + *

    CharityUsers have additional features and priviliges that regular users don't have. Methods + * specified provide the opportunity to save a new name or description. + * + *

    All queries are executed against a MySQL database via a {@link DatabaseConnection}. + */ +public class CharityUserDAO { + + private DatabaseConnection connection; + + /** + * Constructs a new {@code CharityUserDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public CharityUserDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Updates the Charity's name in the {@code CharityVanity} table in the database by getting the + * Charity object in question. + * + * @param charity Charity containing the new name for the database + * @return True or False based on if the update succeed or not + */ + public boolean updateCharityVanityName(Charity charity) { + Connection conn = null; + String sql = + """ + UPDATE CharityVanity SET + charity_name = ? + WHERE UUID_charity = ?; + """; + try { + conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql); + + System.out.println(charity.getUUID().toString()); + ps.setString(1, charity.getName()); + ps.setString(2, charity.getUUID().toString()); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Something went wrong when updating ah"); + return false; + } + } + + /** + * Updates the Charity's description in the {@code CharityVanity} table in the database by getting + * the Charity object in question. + * + * @param charity Charity containing the new name for the database + * @return True or False based on if the update succeed or not + */ + public boolean updateCharityVanityDescription(Charity charity) { + Connection conn = null; + String sql = + """ + UPDATE CharityVanity SET + description = ? + WHERE UUID_charity = ?; + """; + try { + conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql); + + System.out.println(charity.getUUID().toString()); + ps.setString(1, charity.getDescription()); + ps.setString(2, charity.getUUID().toString()); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Something went wrong when updating ah"); + return false; + } + } + + /** + * Gets the Charity that the User is connected to by using {@code CharityUsers} as an + * identifie/bridge. + * + * @param uuid Id of the User. + * @return The Charity the CharityUser is connected to. + */ + public Charity getUserCharityUser(String uuid) { + if (uuid == null || uuid.isBlank()) { + throw new IllegalArgumentException("UUID cannot be null or blank"); + } + Charity currentCharity = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + c.UUID_charities, c.org_number, c.pre_approved, c.status, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + cat.category + FROM CharityUsers cu + INNER JOIN Charities c ON c.UUID_charities = cu.TheCharity + INNER JOIN CharityVanity cv ON cv.UUID_charity = c.UUID_charities + LEFT JOIN Charity_Categories cc ON cc.Charities_UUID_charities = c.UUID_charities + LEFT JOIN Categories cat ON cat.category_id = cc.Categories_category_id + WHERE CharityUserId = ? + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, uuid); + ResultSet rs = stmt.executeQuery(); + + String lastCharity = null; + + while (rs.next()) { + String currentId = rs.getString("UUID_charities"); + if (lastCharity == null || !currentId.equals(lastCharity)) { + currentCharity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + lastCharity = currentId; + } + + String categoryName = rs.getString("category"); + if (categoryName != null && !currentCharity.getCategory().contains(categoryName)) { + currentCharity.getCategory().add(categoryName); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } + return currentCharity; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/DonationDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/DonationDAO.java new file mode 100644 index 00000000..1e6c1cc3 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/DonationDAO.java @@ -0,0 +1,261 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.*; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Donation; +import ntnu.systemutvikling.team6.models.registry.DonationRegistry; +import ntnu.systemutvikling.team6.models.user.User; + +/** + * This class is responsible for sending and receiving concurrent information about the donation to + * and from the Donation Database. Usually called from the Donation related controller, where the + * user is able to view their donations. + */ +public class DonationDAO { + private final DatabaseConnection connection; + + /** + * Constructs a new {@code CharityUserDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public DonationDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Retrieves all donations from the database, each populated with its associated {@link Charity}. + * + *

    The query performs an INNER JOIN between the {@code Donations}, {@code Charities} and {@code + * User} tables on the donations row Charity_id and user_id. Donations without a matching charity + * are excluded from the result. + * + * @return a {@link DonationRegistry} containing all matched donations; never {@code null}, but + * may be empty if no rows are returned + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public DonationRegistry getDonationFromDB() { + DonationRegistry registry = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + d.UUID_Donations, d.amount, d.isAnonymous, d.date, d.charity_id, d.user_id, + c.UUID_charities, c.org_number, c.pre_approved, c.status, + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role + FROM Donations d + INNER JOIN Charities c ON d.charity_id = c.UUID_charities + INNER JOIN User u ON d.user_id = u.UUID_user + """; + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql_query); + + registry = new DonationRegistry(); + while (rs.next()) { + Charity charity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getBoolean("pre_approved"), + rs.getString("status")); + + User user = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + Donation donation = + new Donation( + rs.getString("UUID_Donations"), + rs.getDouble("amount"), + rs.getDate("date").toLocalDate(), + charity, + user, + rs.getBoolean("isAnonymous")); + registry.addDonation(donation); + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } + return registry; + } + + /** + * Retrieves all donation data from the {@code Donations} table for a spesific user using its ID. + * + *

    Query selects from {@code Donations}, then INNER JOINS with {@code Charities} and {@code + * CharityVanity} to get names among other thing, and {@code User} table to get the donor. At the + * end uses a WHERE-clause to get the specified User. + * + * @param uuid the java.UUID for the user but in string. + * @return Returns a DOnationRegistry with all donations. + */ + public DonationRegistry getDonationForUser(String uuid) { + DonationRegistry registry = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + d.UUID_Donations, d.amount, d.isAnonymous, d.date, d.charity_id, d.user_id, + c.UUID_charities, c.org_number, c.pre_approved, c.status, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role + FROM Donations d + INNER JOIN Charities c ON d.charity_id = c.UUID_charities + INNER JOIN CharityVanity cv ON cv.UUID_charity = c.UUID_charities + INNER JOIN User u ON d.user_id = u.UUID_user + WHERE d.user_id = ? + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, uuid); + ResultSet rs = stmt.executeQuery(); + + registry = new DonationRegistry(); + while (rs.next()) { + Charity charity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + User user = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + Donation donation = + new Donation( + rs.getString("UUID_Donations"), + rs.getDouble("amount"), + rs.getDate("date").toLocalDate(), + charity, + user, + rs.getBoolean("isAnonymous")); + registry.addDonation(donation); + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } + return registry; + } + + /** + * Retrieves all donation data from the {@code Donations} table for a specific Charity using its + * ID. + * + *

    Mostly used by Charity Users to view how much money they have. Query selects from {@code + * Donations}, then INNER JOINS with {@code Charities} and {@code CharityVanity} to get names + * among other thing, and {@code User} table to get the donor. At the end uses a WHERE - clause to + * get the Charity in question. + * + * @param uuid the java.UUID for the user but in string. + * @return Returns a DOnationRegistry with all donations. + */ + public DonationRegistry getDonationForCharity(String uuid) { + DonationRegistry registry = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + d.UUID_Donations, d.amount, d.isAnonymous, d.date, d.charity_id, d.user_id, + c.UUID_charities, c.org_number, c.pre_approved, c.status, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role + FROM Donations d + INNER JOIN Charities c ON d.charity_id = c.UUID_charities + INNER JOIN CharityVanity cv ON cv.UUID_charity = c.UUID_charities + INNER JOIN User u ON d.user_id = u.UUID_user + WHERE c.UUID_charities = ? + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, uuid); + ResultSet rs = stmt.executeQuery(); + + registry = new DonationRegistry(); + while (rs.next()) { + Charity charity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + User user = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + Donation donation = + new Donation( + rs.getString("UUID_Donations"), + rs.getDouble("amount"), + rs.getDate("date").toLocalDate(), + charity, + user, + rs.getBoolean("isAnonymous")); + registry.addDonation(donation); + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } + return registry; + } + + /** + * Gets a Donation object for a given charity and by a User, and sends it to the database through + * MySQL. + * + * @param donation Donation object containing all relevant information to send to database. + */ + public void addDonation(Donation donation) { + String sql_query = + """ + INSERT INTO Donations (UUID_Donations, amount, isAnonymous, date, charity_id, user_id) + VALUES (?, ?, ?, ?, ?, ?) + """; + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql_query)) { + conn.setAutoCommit(false); + + ps.setString(1, donation.getDonationID().toString()); + ps.setDouble(2, donation.getAmount()); + ps.setBoolean(3, donation.getDonor().getSettings().isAnonymous()); + ps.setDate(4, Date.valueOf(donation.getDate())); + ps.setString(5, donation.getCharity().getUUID().toString()); + ps.setString(6, donation.getDonor().getId().toString()); + + ps.executeUpdate(); + conn.commit(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAO.java new file mode 100644 index 00000000..f9450288 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAO.java @@ -0,0 +1,184 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; +import ntnu.systemutvikling.team6.models.user.User; + +/** + * Data access class responsible for getting managing favourites for a logged inn user in the + * application. + * + *

    Methods include gettng users favourites, adding a favourite and checking if the charity was + * favourited. + * + *

    All queries are executed against a MySQL database via a {@link DatabaseConnection}. + */ +public class FavouritesDAO { + + private final DatabaseConnection connection; + + /** + * Constructs a new {@code FavouritesDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public FavouritesDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Checks if both {@code User} and {@code Charity} are in the same row in the {@code + * User_has_favourites } table. If it is, the charity is considered a favourite by the User + * + *

    Uses a Select query with a WHERE-clause that searches for a row with both ids, which + * considered a favourite. + * + * @param user User in question + * @param charity Charity in question of being favourite by User. + * @return + */ + public boolean isFavourite(User user, Charity charity) { + String sql = "SELECT * FROM User_has_favourites WHERE Favourer = ? AND Favourite_Charity = ?"; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + + ps.setString(1, user.getId().toString()); + ps.setString(2, charity.getUUID().toString()); + + ResultSet rs = ps.executeQuery(); + return rs.next(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Send a quick insert query to the {@code User_has_favourites} table, adding a row with favourer + * and the favourite Charity + * + * @param user User or the Favourer in the database + * @param charity Favourite charity in question. + * @return True or False based on if it succeeded or not + */ + public boolean addFavourite(User user, Charity charity) { + String sql = "INSERT INTO User_has_favourites (Favourer, Favourite_charity) VALUES (?, ?)"; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + + ps.setString(1, user.getId().toString()); + ps.setString(2, charity.getUUID().toString()); + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Does a quick remove query to delete a previous favourite charity. + * + *

    This will not invoke and Argument-Exception because the remove query is avabile only after + * being added throught {@code addFavourite} + * + * @param user user in question of having a favourite + * @param charity Charity about to be removed a favourite + * @return + */ + public boolean removeFavourite(User user, Charity charity) { + String sql = "DELETE FROM User_has_favourites WHERE Favourer = ? AND Favourite_charity = ?"; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + + ps.setString(1, user.getId().toString()); + ps.setString(2, charity.getUUID().toString()); + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Get all detailts about the users favourites. + * + *

    Uses a Select-query, INNER JOIN between {@code Charities} and {@code CharityVanity} tables, + * and LEFT JOIN {@code Charity_Categories} and {@code Categries} tables to get fill all + * attributes in the {@code Charity} object. At the end, uses a WHERE-clause to grab the right + * favourer. + * + * @param user_id UUID in String for the Favourer + * @return An empty or non-empty List of Charities that have been favourited by User + */ + public List getFavouritesForUser(String user_id) { + CharityRegistry registry = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + uf.Favourite_Charity, + c.UUID_charities, c.org_number, c.pre_approved, c.status, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + cat.category + FROM User_has_favourites uf + INNER JOIN Charities c ON uf.Favourite_Charity = c.UUID_charities + INNER JOIN CharityVanity cv ON uf.Favourite_Charity = cv.UUID_charity + LEFT JOIN Charity_Categories cc ON cc.Charities_UUID_charities = c.UUID_charities + LEFT JOIN Categories cat ON cat.category_id = cc.Categories_category_id + WHERE Favourer = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, user_id); + ResultSet rs = stmt.executeQuery(); + + Charity currentCharity = null; + + registry = new CharityRegistry(); + while (rs.next()) { + String currentId = rs.getString("UUID_charities"); + if (currentCharity == null || !currentId.equals(currentCharity.getUUID().toString())) { + System.out.println("Adding Charities"); + currentCharity = + new Charity( + rs.getString("UUID_charities"), + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + registry.addCharity(currentCharity); + } + + String categoryName = rs.getString("category"); + if (categoryName != null & !currentCharity.getCategory().contains(categoryName)) { + currentCharity.getCategory().add(categoryName); + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating."); + } finally { + conn = null; + } + return registry.getAllCharities(); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FeedbackDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FeedbackDAO.java new file mode 100644 index 00000000..e546e87b --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/FeedbackDAO.java @@ -0,0 +1,128 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.*; +import java.time.LocalDate; +import java.util.ArrayList; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.Feedback; +import ntnu.systemutvikling.team6.models.user.Language; +import ntnu.systemutvikling.team6.models.user.Settings; +import ntnu.systemutvikling.team6.models.user.User; + +/** + * This Data Access Object is mainly responsible for handling Feedbacks and communitcating with the + * DataBase. Primarily interacting with the {@code Feedback} table. + */ +public class FeedbackDAO { + private final DatabaseConnection connection; + + /** + * Constructs a new {@code FeedbackDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public FeedbackDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Send a simple insert query to the {@code Feedback} table. Containing the comment, date, if its + * an Anonymous Feedback and recipients. + * + * @param feedback Feedback object contain all relevant info, as said above. + * @param toCharity Dedicated Charity object, the recipient. + * @return + */ + public boolean addFeedbackToCharity(Feedback feedback, Charity toCharity) { + String sql = + """ + INSERT INTO Feedback + (UUID_feedback, feedback_comment, feedback_date, isAnonymous, charity_id, user_id) + VALUES (?, ?, ?, ?, ?, ?); + + """; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + + ps.setString(1, feedback.getFeedbackId().toString()); + ps.setString(2, feedback.getComment()); + ps.setDate(3, Date.valueOf(feedback.getDate())); + ps.setBoolean(4, feedback.getUser().getSettings().isAnonymous()); + ps.setString(5, toCharity.getUUID().toString()); + ps.setString(6, feedback.getUser().getId().toString()); + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + /** + * A helper function that retrieves all feedback entries associated with a specific charity, + * identified by its UUID. Currently, has no use. + * + *

    Each {@link Feedback} object is populated with the associated {@link User} (without settings + * or inbox data). The query uses a LEFT JOIN between the {@code Feedback} and {@code User} + * tables, filtered by {@code charity_id}. + * + * @param charity_uuid the UUID of the charity whose feedback should be retrieved; must not be + * {@code null} + * @return an {@link ArrayList} of {@link Feedback} objects for the given charity; returns an + * empty list if no feedback exists for that charity + * @throws RuntimeException if any exception occurs while executing the query, wrapping the + * original cause + */ + public ArrayList getFeedbackforCharityUUID(String charity_uuid) { + ArrayList Feedbacks = new ArrayList<>(); + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + f.UUID_feedback, f.feedback_comment, f.feedback_date, f.isAnonymous, f.charity_id, f.user_id, + u.UUID_user, u.user_name, u.user_email, u.user_password, u.role, + s.language, s.lightmode + FROM Feedback f + LEFT JOIN User u ON f.user_id = u.UUID_user + RIGHT JOIN Settings s ON u.UUID_user = s.UUID_user + WHERE f.charity_id = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, charity_uuid); + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + User userWithSettingsAndNoInbox = + new User( + rs.getString("UUID_User"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + userWithSettingsAndNoInbox.setSettings( + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language")), + rs.getBoolean("lightmode"))); + Feedback feedback = + new Feedback( + rs.getString("UUID_feedback"), + userWithSettingsAndNoInbox, + rs.getString("feedback_comment"), + LocalDate.parse(rs.getString("feedback_date"))); + Feedbacks.add(feedback); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + conn = null; + } + return Feedbacks; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/MessageDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/MessageDAO.java new file mode 100644 index 00000000..3d141d84 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/MessageDAO.java @@ -0,0 +1,108 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.user.Message; + +/** + * This Data Access Object is mainly responsible for handling Messages and Message object to + * communitcate correctly with the DataBase. Primarily interacting with the {@code Messages} table. + */ +public class MessageDAO { + private final DatabaseConnection connection; + + /** + * Constructs a new {@code FeedbackDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public MessageDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Uses a repeated INSERT-query to send a message to all donor (as in Users that have donated). + * + *

    First grabs all donors (all Users that have donated to the charity) ids by getting the + * Charity_id throught the attribute. + * + * @param message Message object contain all relevant info, including the Charity id. + * @return True or False based on if it succeeded or not + */ + public boolean addMessage(Message message) { + // First fetch all unique donors for this charity + List donorIds = getDonorIdsForCharity(message.getFrom().getUUID().toString()); + + if (donorIds.isEmpty()) return false; + String sql = + """ + INSERT INTO Messages + (UUID_message, message_title, message_content, message_date, sender_charity_id, user_id) + VALUES (?, ?, ?, ?, ?, ?) + """; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + for (String donorId : donorIds) { + stmt.setString(1, UUID.randomUUID().toString()); + stmt.setString(2, message.getTitle()); + stmt.setString(3, message.getContent()); + stmt.setDate(4, Date.valueOf(message.getTimeAndDate())); + stmt.setString(5, message.getFrom().getUUID().toString()); + stmt.setString(6, donorId); + stmt.addBatch(); + } + + int[] results = stmt.executeBatch(); + return results.length > 0; + + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Failed to send messages to donors."); + } + } + + /** + * Private helper function used in {@code addMessage} method, which finds all distinct User Ids + * that have donated to given Charity. + * + *

    Uses a Select query with a distinct modifier to not get duplicate user_id. At the end uses + * an WHERE-clause to get the spesified charity. + * + * @param charityId Charity's I'd to search for. + * @return An empty or non-empty list of Ids as String. + */ + private List getDonorIdsForCharity(String charityId) { + List donorIds = new ArrayList<>(); + String sql = + """ + SELECT DISTINCT user_id + FROM Donations + WHERE charity_id = ? + """; + + try (Connection conn = connection.getMySqlConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + stmt.setString(1, charityId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + donorIds.add(rs.getString("user_id")); + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Failed to fetch donor IDs."); + } + return donorIds; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/UserDAO.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/UserDAO.java new file mode 100644 index 00000000..c3627149 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DAO/UserDAO.java @@ -0,0 +1,632 @@ +package ntnu.systemutvikling.team6.database.DAO; + +import java.sql.*; +import java.time.LocalDate; +import java.util.HashSet; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.registry.UserRegistry; +import ntnu.systemutvikling.team6.models.user.*; +import ntnu.systemutvikling.team6.security.PasswordHasher; + +/** + * This class is responsible for sending concurrent information about the user to the User database, + * and user settings to the settings database. + * + * @author Robin Strand Prestmo + * @author Adrian Paul Limpiado Balunan + */ +public class UserDAO { + + private final DatabaseConnection connection; + + /** + * Constructs a new {@code UserDAO} with the given database connection. + * + * @param connection the {@link DatabaseConnection} to use for executing queries; must not be + * {@code null} + */ + public UserDAO(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Uses a select query to check if the provided Email already exists in {@code User} table. Return + * value is based on if finds a row or not. + * + *

    Check if email is a valid email. Uses a Select query to get a row containing the provided + * email. If it exists, return true. If not, return false Used in tandem with {@code + * LoginPageController} prevent duplicate Emails appearing on database. + * + * @param email Email in question. Check + * @return + */ + public boolean isEmailTaken(String email) { + if (email == null || email.isBlank() || !email.contains("@") || !email.contains(".")) { + throw new IllegalArgumentException( + "Email cannot be null or blank," + " and must contain '@' and '.'"); + } + try (Connection conn = connection.getMySqlConnection()) { + + String mysql = + """ + SELECT UUID_User FROM User WHERE user_email = ? + """; + PreparedStatement statement = conn.prepareStatement(mysql); + statement.setString(1, email); + ResultSet rs = statement.executeQuery(); + + if (rs.next()) { + System.out.println("Email Taken already"); + return true; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Retrieves a single {@link User} from the database by their UUID. + * + *

    The returned user is fully populated with {@link Settings} (when present) and an {@link + * Inbox} containing any associated {@link Message} objects. Returns {@code null} if no user with + * the given UUID exists. + * + * @param user_id the UUID string of the user to retrieve; must not be {@code null} + * @return the matching {@link User} with settings and inbox populated, or {@code null} if no user + * is found + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public User getUserFromDBUuid(String user_id) { + User user = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role, + s.UUID_user, s.isAnonymous, s.language, s.lightmode, + m.UUID_message, m.message_title, m.message_content, m.message_date, m.sender_user_id, m.sender_charity_id, m.user_id, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + c.UUID_charities, c.org_number, c.pre_approved, c.status + FROM User u + LEFT JOIN Settings s ON u.UUID_User = s.UUID_user + LEFT JOIN Messages m ON u.UUID_User = m.user_id + LEFT JOIN Charities c ON m.sender_charity_id = c.UUID_charities + LEFT JOIN CharityVanity cv ON c.UUID_charities = cv.UUID_charity + WHERE u.UUID_User = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, user_id); + ResultSet rs = stmt.executeQuery(); + + String lastUserid = null; + HashSet addedMessageIds = new HashSet<>(); + while (rs.next()) { + String userId = rs.getString("UUID_User"); + if (lastUserid == null || !userId.equals(lastUserid)) { + user = + new User( + userId, + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + if (rs.getString("isAnonymous") != null) { + Settings settings = + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language").toUpperCase()), + rs.getBoolean("lightmode")); + user.setSettings(settings); + } + user.setInbox(new Inbox()); + lastUserid = userId; + } + String messageId = rs.getString("UUID_message"); + if (messageId != null && !addedMessageIds.contains(messageId)) { + addedMessageIds.add(messageId); + Charity fromCharity = null; + String charityId = rs.getString("UUID_charities"); + if (charityId != null) { + fromCharity = + new Charity( + charityId, + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + } + + if (fromCharity != null) { + Message message = + new Message( + rs.getString("message_title"), + fromCharity, + rs.getString("message_content"), + LocalDate.parse(rs.getString("message_date"))); + user.getInbox().addMessage(message); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + return user; + } + + /** + * Retrieves a single {@link User} from the database matching the given username and password. + * + *

    The password is hashed via {@link PasswordHasher} before being compared against the stored + * value. If a matching user is found, their {@link Settings} (when present) and {@link Inbox} + * (including any {@link Message} objects) are also populated. Returns {@code null} if no matching + * user is found. + * + *

    Note: the current SQL query compares both parameters against {@code + * user_password}; the {@code user_name} column is not yet included in the WHERE clause, which may + * be a bug. + * + * @param email the email to look up + * @param password the plain-text password; hashed internally before the query runs + * @return the matching {@link User} with settings and inbox populated, or {@code null} if no + * match is found + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public User getUserFromDBEmailAndPassword(String email, String password) { + PasswordHasher hasher = new PasswordHasher(); + String hashedpassword = hasher.getHashPassword(password); + + User user = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role, + s.UUID_user, s.isAnonymous, s.language, s.lightmode, + m.UUID_message, m.message_title, m.message_content, m.message_date, m.sender_user_id, m.sender_charity_id, m.user_id, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + c.UUID_charities, c.org_number, c.pre_approved, c.status + FROM User u + LEFT JOIN Settings s ON u.UUID_User = s.UUID_user + LEFT JOIN Messages m ON u.UUID_User = m.user_id + LEFT JOIN Charities c ON m.sender_charity_id = c.UUID_charities + LEFT JOIN CharityVanity cv ON c.UUID_charities = cv.UUID_charity + WHERE u.user_email = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, email); + + ResultSet rs = stmt.executeQuery(); + HashSet addedMessageIds = new HashSet<>(); + while (rs.next()) { + String userId = rs.getString("UUID_User"); + System.out.println(rs.getString("user_name")); + + if (user == null) { + String storedHash = rs.getString("user_password"); + + if (!new PasswordHasher().isValidPassword(password, storedHash)) { + return null; + } + user = + new User( + userId, + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + if (rs.getString("isAnonymous") != null) { + Settings settings = + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language").toUpperCase()), + rs.getBoolean("lightmode")); + user.setSettings(settings); + } + user.setInbox(new Inbox()); + } + String messageId = rs.getString("UUID_message"); + if (messageId != null && !addedMessageIds.contains(messageId)) { + addedMessageIds.add(messageId); + Charity fromCharity = null; + String charityId = rs.getString("UUID_charities"); + if (charityId != null) { + fromCharity = + new Charity( + charityId, + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + } + + if (fromCharity != null) { + Message message = + new Message( + rs.getString("message_title"), + fromCharity, + rs.getString("message_content"), + LocalDate.parse(rs.getString("message_date"))); + user.getInbox().addMessage(message); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + return user; + } + + /** + * Retrieves all users from the database, each fully populated with their {@link Settings} and + * {@link Inbox}. + * + *

    The query LEFT JOINs {@code User}, {@code Settings}, and {@code Messages}. Multiple rows for + * the same user UUID (due to multiple messages) are collapsed into a single {@link User} object + * with all messages appended to its inbox. + * + * @return a {@link UserRegistry} containing all users found in the database; never {@code null}, + * but may be empty if no users exist + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public UserRegistry getUsersFromDB() { + UserRegistry registry = new UserRegistry(); + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + u.UUID_User, u.user_name, u.user_email, u.user_password, u.role, + s.UUID_user, s.isAnonymous, s.language, s.lightmode, + m.UUID_message, m.message_title, m.message_content, m.message_date, m.sender_user_id, m.sender_charity_id, m.user_id, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + c.UUID_charities, c.org_number, c.pre_approved, c.status + FROM User u + LEFT JOIN Settings s ON u.UUID_User = s.UUID_user + LEFT JOIN Messages m ON u.UUID_User = m.user_id + LEFT JOIN Charities c ON m.sender_charity_id = c.UUID_charities + LEFT JOIN CharityVanity cv ON c.UUID_charities = cv.UUID_charity + """; + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql_query); + + User currentUser = null; + String lastUserid = null; + HashSet addedMessageIds = new HashSet<>(); + + while (rs.next()) { + String userId = rs.getString("UUID_User"); + + if (lastUserid == null || !userId.equals(lastUserid)) { + currentUser = + new User( + userId, + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); + if (rs.getString("isAnonymous") != null) { + Settings settings = + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language").toUpperCase()), + rs.getBoolean("lightmode")); + currentUser.setSettings(settings); + } + currentUser.setInbox(new Inbox()); + registry.addUser(currentUser); + lastUserid = userId; + } + String messageId = rs.getString("UUID_message"); + if (messageId != null && !addedMessageIds.contains(messageId)) { + addedMessageIds.add(messageId); + Charity fromCharity = null; + String charityId = rs.getString("UUID_charities"); + if (charityId != null) { + fromCharity = + new Charity( + charityId, + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + } + + if (fromCharity != null) { + Message message = + new Message( + rs.getString("message_title"), + fromCharity, + rs.getString("message_content"), + LocalDate.parse(rs.getString("message_date"))); + currentUser.getInbox().addMessage(message); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + return registry; + } + + /** + * Retrieves the {@link Inbox} for a specific user by their UUID, populated with all of their + * {@link Message} objects. + * + *

    Returns an empty {@link Inbox} (never {@code null}) if no messages exist for the given user. + * + * @param user_id the UUID string of the user whose inbox should be retrieved; must not be {@code + * null} + * @return an {@link Inbox} containing all messages for the user; empty if no messages are found + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public Inbox getInboxForUser(String user_id) { + Inbox inbox = new Inbox(); + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT + m.UUID_message, m.message_title, m.message_content, m.message_date, m.sender_user_id, m.sender_charity_id, m.user_id, + cv.charity_name, cv.charity_link, cv.description, cv.logoURL, cv.key_values, cv.logoBLOB, + c.UUID_charities, c.org_number, c.pre_approved, c.status + FROM Messages m + LEFT JOIN Charities c ON m.sender_charity_id = c.UUID_charities + LEFT JOIN CharityVanity cv ON c.UUID_charities = cv.UUID_charity + WHERE user_id = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, user_id); + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + Charity fromCharity = null; + String charityId = rs.getString("UUID_charities"); + if (charityId != null) { + fromCharity = + new Charity( + charityId, + rs.getString("org_number"), + rs.getString("charity_name"), + rs.getString("charity_link"), + rs.getString("status"), + rs.getBoolean("pre_approved"), + rs.getString("description"), + rs.getString("logoURL"), + rs.getString("key_values"), + rs.getBytes("logoBLOB")); + } + + if (fromCharity != null) { + Message message = + new Message( + rs.getString("message_title"), + fromCharity, + rs.getString("message_content"), + LocalDate.parse(rs.getString("message_date"))); + inbox.addMessage(message); + } + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + return inbox; + } + + /** + * Retrieves the {@link Settings} for a specific user by their UUID. + * + *

    At most one row is fetched (via {@code setMaxRows(1)}). Returns {@code null} if no settings + * row exists for the given user. + * + * @param user_id the UUID string of the user whose settings should be retrieved; must not be + * {@code null} + * @return the user's {@link Settings}, or {@code null} if none are found + * @throws RuntimeException if a {@link SQLException} occurs while executing the query + */ + public Settings getSettingsForUser(String user_id) { + Settings settings = null; + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + String sql_query = + """ + SELECT UUID_user, isAnonymous, language, lightmode FROM Settings + WHERE UUID_user = ?; + """; + PreparedStatement stmt = conn.prepareStatement(sql_query); + stmt.setString(1, user_id); + stmt.setMaxRows(1); + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + settings = + new Settings( + rs.getBoolean("isAnonymous"), + Language.valueOf(rs.getString("language").toUpperCase()), + rs.getBoolean("lightmode")); + } + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + conn = null; + } + + return settings; + } + + /** + * Gets the user and settings information and sends it to the database through MySQL. + * + * @param user the user to be saved in the database. + * @throws RuntimeException if a database error occurs during the operation + * @return true or false based on if the register is a success or not + */ + public boolean registerUser(User user) { + String userSql = + """ + INSERT INTO User ( + UUID_User, + user_name, + user_email, + user_password, + role + ) + VALUES (?, ?, ?, ?, ?) + """; + + String settingsSql = + """ + INSERT INTO Settings ( + UUID_user, + isAnonymous, + language, + lightmode + ) + VALUES (?, ?, ?, ?) + """; + + int psUserRows = 0; + int psSettingsRows = 0; + + try (Connection conn = connection.getMySqlConnection()) { + + conn.setAutoCommit(false); + + try (PreparedStatement psUser = conn.prepareStatement(userSql)) { + + psUser.setString(1, user.getId().toString()); + psUser.setString(2, user.getUsername()); + psUser.setString(3, user.getEmail()); + psUser.setString(4, user.getPasswordHash()); + psUser.setString(5, user.getRole().name()); + + psUserRows = psUser.executeUpdate(); + } + + try (PreparedStatement psSettings = conn.prepareStatement(settingsSql)) { + + psSettings.setString(1, user.getId().toString()); + psSettings.setBoolean(2, user.getSettings().isAnonymous()); + psSettings.setString(3, user.getSettings().getLanguage().name()); + psSettings.setBoolean(4, user.getSettings().isLightMode()); + + psSettingsRows = psSettings.executeUpdate(); + } + + conn.commit(); + + return psUserRows > 0 && psSettingsRows > 0; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Updates the Users settings in the {@code Settings} table. New values are stored in the Settings + * object. + * + * @param user User that is going to recieve changes + * @param settings Settings object containing new attributes + * @return True or False based on if the update succeed or not + */ + public boolean updateUserSettings(User user, Settings settings) { + Connection conn = null; + String sql = + """ + UPDATE Settings SET + isAnonymous = ?, + language = ?, + lightmode = ? + WHERE UUID_user = ?; + """; + try { + conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql); + + ps.setBoolean(1, settings.isAnonymous()); + ps.setString(2, settings.getLanguage().name()); + ps.setBoolean(3, settings.isLightMode()); + ps.setString(4, user.getId().toString()); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Something went wrong when updating Settings"); + return false; + } + } + + /** + * Updates the Users name, email and password in the {@code User} table. New values are stored in + * oncoming User param. + * + * @param user User that is going to recieve changes + * @return True or False based on if the update succeed or not + */ + public boolean updateUserDetails(User user) { + Connection conn = null; + String sql = + """ + UPDATE User SET + user_name = ?, + user_email = ?, + user_password = ? + WHERE UUID_User = ?; + """; + try { + conn = connection.getMySqlConnection(); + PreparedStatement ps = conn.prepareStatement(sql); + + ps.setString(1, user.getUsername()); + ps.setString(2, user.getEmail()); + ps.setString(3, user.getPasswordHash()); + ps.setString(4, user.getId().toString()); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Something went wrong when updating Settings"); + return false; + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java deleted file mode 100644 index a4007a05..00000000 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java +++ /dev/null @@ -1,299 +0,0 @@ -package ntnu.systemutvikling.team6.database; - -import java.sql.*; -import java.util.List; -import java.util.UUID; -import ntnu.systemutvikling.team6.models.Charity; -import ntnu.systemutvikling.team6.models.CharityRegistry; -import ntnu.systemutvikling.team6.models.Donation; -import ntnu.systemutvikling.team6.models.DonationRegistry; -import ntnu.systemutvikling.team6.scraper.APICharityData; - -/** - * Manages the Database with MySQL tables and JDBC. - * - *

    This class is responsible for creating the tables needed for the application, if not done - * already and maintaining the {@code charities} table based on data retrieved from the IK API. It - * is also responsible for retrieving the data from the database and sending it to the application - * through the CharityRegistry and DonationRegistry. It is used by the FrontpageController to - * retrieve the data needed to display the charities - */ -public class DatabaseManager { - private final DatabaseConnection connection; - - /** - * Contractor for DatabaseManager. It uses a DatabaseConnection object that contains a connection - * credentials. - */ - public DatabaseManager() { - this.connection = new DatabaseConnection(); - } - - /** - * Connection test for the Database. Does a simple SELECT SQL query and returns either true og and - * Exception if failed - * - * @return true if Sucsedd or SQLExepction if failed - */ - public boolean testConnection() { - try (Connection conn = connection.getMySqlConnection(); - Statement stmt = conn.createStatement()) { - - ResultSet rs = stmt.executeQuery("SELECT 1"); - - if (rs.next()) { - System.out.println("Database connection verified."); - return true; - } - - } catch (SQLException e) { - System.out.println("Database connection failed."); - e.printStackTrace(); - } - - return false; - } - - /** - * Creates the {@code Charities} and {@code Donations} tables if they do not already exist. - * - *

    The table structure for Charities is based on fields from {@link APICharityData}. - * - * @throws RuntimeException if a {@link SQLException} occurs while creating the table - */ - public void createTables() { - String sql_query1 = - """ - -- ----------------------------------------------------- - -- Table `HelpMeHelp`.`Charities` - -- ----------------------------------------------------- - CREATE TABLE IF NOT EXISTS Charities ( - UUID_charities CHAR(36) PRIMARY KEY, - org_number VARCHAR(255) NOT NULL, - charity_name VARCHAR(255) NOT NULL, - charity_link VARCHAR(255) NOT NULL, - pre_approved TINYINT NOT NULL, - status VARCHAR(255) NOT NULL, - UNIQUE KEY unique_org_number (org_number) - ) ENGINE=InnoDB; - - - """; - String sql_query2 = - """ - -- ----------------------------------------------------- - -- Table `HelpMeHelp`.`Donations` - -- ----------------------------------------------------- - CREATE TABLE IF NOT EXISTS Donations ( - `UUID_Donations` CHAR(36) NOT NULL, - `amount` DECIMAL NOT NULL, - `date` DATE NOT NULL, - `Charities_UUID_charities` CHAR(36) NOT NULL, - PRIMARY KEY (`UUID_Donations`), - INDEX `fk_Donations_Charities_idx` (`Charities_UUID_charities` ASC) VISIBLE, - CONSTRAINT `fk_Donations_Charities` - FOREIGN KEY (`Charities_UUID_charities`) - REFERENCES Charities (`UUID_charities`) - ON DELETE CASCADE - ON UPDATE CASCADE) - ENGINE = InnoDB; - """; - - try (Connection conn = connection.getMySqlConnection(); - Statement s = conn.createStatement()) { - - s.execute(sql_query1); - s.execute(sql_query2); - } catch (SQLException e) { - e.printStackTrace(); - throw new RuntimeException("Error creating table."); - } - } - - /** - * This method is used to verify the integrity of the data in the {@code charities} table and to - * update it based on the data retrieved from the IK API. The param charities are retrieved from - * the IK API through the APICharityData class. Called in initialize method in - * HmHApplication.java, which is the main class of the application, to ensure that the data is up - * to date when the application starts. Uses a a temp table to ensure that the data in the - * database is consistent with the data from the API. - * - * @param charities - */ - public void addAPIDataToTable(List charities) { - Connection conn = null; - try { - conn = connection.getMySqlConnection(); - conn.setAutoCommit(false); - String sql_query = - """ - INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, pre_approved, status) - VALUES (?, ?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE - charity_name = VALUES(charity_name), - charity_link = VALUES(charity_link), - pre_approved = VALUES(pre_approved), - status = VALUES(status) - """; - - try (PreparedStatement ps = conn.prepareStatement(sql_query)) { - for (Charity charity : charities) { - if (charity.getUUID() == null) { - ps.setString(1, UUID.randomUUID().toString()); - } else { - ps.setString(1, charity.getUUID().toString()); - } - - ps.setString(2, charity.getOrg_number().replaceAll("\\s", "")); - ps.setString(3, charity.getName()); - ps.setString(4, charity.getDescription()); - ps.setBoolean(5, charity.getPreApproved()); // Description is the link - ps.setString(6, charity.getStatus()); - - ps.addBatch(); - } - ps.executeBatch(); - } - - // -- Intergerty Check: - String createTemp = - """ - CREATE TEMPORARY TABLE temp_api_charities ( - org_number VARCHAR(20) PRIMARY KEY - ) - """; - - try (PreparedStatement ps = conn.prepareStatement(createTemp)) { - ps.execute(); - } - - String insertTemp = "INSERT IGNORE INTO temp_api_charities (org_number) VALUES (?)"; - - try (PreparedStatement ps = conn.prepareStatement(insertTemp)) { - - for (Charity charity : charities) { - ps.setString(1, charity.getOrg_number().replaceAll("\\s", "")); - ps.addBatch(); - } - - ps.executeBatch(); - } - - String deleteSql = - """ - DELETE FROM Charities c - WHERE NOT EXISTS ( - SELECT 1 - FROM temp_api_charities t - WHERE t.org_number = c.org_number - ) - """; - - try (PreparedStatement ps = conn.prepareStatement(deleteSql)) { - ps.executeUpdate(); - } - - conn.commit(); - - } catch (SQLException e) { - if (conn != null) { - try { - conn.rollback(); - } catch (SQLException ex) { - ex.printStackTrace(); - } - } - e.printStackTrace(); - - throw new RuntimeException("ERROR: Something went wrong during updating charities table."); - } finally { - if (conn != null) { - try { - conn.setAutoCommit(true); - conn.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - } - } - - public CharityRegistry getCharitiesFromDB() { - CharityRegistry registry = null; - Connection conn = null; - try { - conn = connection.getMySqlConnection(); - String sql_query = - "SELECT UUID_charities, org_number, charity_name, charity_link, pre_approved, status FROM Charities"; - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql_query); - - registry = new CharityRegistry(); - while (rs.next()) { - Charity charity = - new Charity( - rs.getString("UUID_charities"), - rs.getString("org_number"), - rs.getString("charity_link"), - rs.getString("charity_name"), - rs.getBoolean("pre_approved"), - rs.getString("status")); - registry.addCharity(charity); - } - } catch (SQLException e) { - e.printStackTrace(); - throw new RuntimeException("ERROR: Something went wrong during updating charities table."); - } - return registry; - } - - public DonationRegistry getDonationFromDB() { - DonationRegistry registry = null; - Connection conn = null; - try { - conn = connection.getMySqlConnection(); - String sql_query = - """ - SELECT - d.UUID_Donations, - d.amount, - d.date, - c.UUID_charities, - c.org_number, - c.charity_name, - c.charity_link, - c.pre_approved, - c.status - FROM Donations d - JOIN Charities c - ON d.Charities_UUID_charities = c.UUID_charities - """; - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql_query); - - registry = new DonationRegistry(); - while (rs.next()) { - Charity charity = - new Charity( - rs.getString("UUID_charities"), - rs.getString("org_number"), - rs.getString("charity_name"), - rs.getString("charity_link"), - rs.getBoolean("pre_approved"), - rs.getString("status")); - - Donation donation = - new Donation( - rs.getString("UUID_Donations"), - rs.getDouble("amount"), - rs.getDate("date").toLocalDate(), - charity); - registry.addDonation(donation); - } - } catch (SQLException e) { - e.printStackTrace(); - throw new RuntimeException("ERROR: Something went wrong during updating charities table."); - } - return registry; - } -} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java new file mode 100644 index 00000000..8d8d69bb --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java @@ -0,0 +1,317 @@ +package ntnu.systemutvikling.team6.database; + +import java.sql.*; +import ntnu.systemutvikling.team6.models.*; +import ntnu.systemutvikling.team6.models.user.*; + +/** + * Manages the Database with MySQL tables and test connection. + * + *

    This class object is able to create MySQL to ntnu localized database and able to + * testConnection to it. + */ +public class DatabaseSetup { + private final DatabaseConnection connection; + + /** + * Contractor for DatabaseManager. It uses a DatabaseConnection object that contains a connection + * credentials. + */ + public DatabaseSetup(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * Connection test for the Database. Does a simple SELECT SQL query and returns either true og and + * Exception if failed + * + * @return true if Sucsedd or SQLExepction if failed + */ + public boolean testConnection() { + try (Connection conn = connection.getMySqlConnection(); + Statement stmt = conn.createStatement()) { + + ResultSet rs = stmt.executeQuery("SELECT 1"); + + if (rs.next()) { + System.out.println("Database connection verified."); + return true; + } + + } catch (SQLException e) { + System.out.println("Database connection failed."); + e.printStackTrace(); + } + return false; + } + + /** + * Creates the {@code Charities} and {@code Donations} tables if they do not already exist. + * + * @throws RuntimeException if a {@link SQLException} occurs while creating the table + */ + public void createTables() { + String charitiesTable = + """ + -- ----------------------------------------------------- + -- Table `HelpMeHelp`.`Charities` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Charities` ( + `UUID_charities` CHAR(36) NOT NULL, + `org_number` VARCHAR(255) NOT NULL, + `pre_approved` TINYINT NOT NULL, + `status` VARCHAR(255) NOT NULL, + PRIMARY KEY (`UUID_charities`), + UNIQUE INDEX `org_number_UNIQUE` (`org_number` ASC) VISIBLE) + ENGINE = InnoDB; + """; + String donationsTable = + """ + -- ----------------------------------------------------- + -- Table `HelpMeHelp`.`Donations` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Donations` ( + `UUID_Donations` CHAR(36) NOT NULL, + `amount` DECIMAL NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `date` DATE NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_Donations`), + INDEX `fk_Donations_Charities_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Donations_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Donations_Charities` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Donations_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + String userTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`User` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`User` ( + `UUID_User` CHAR(36) NOT NULL, + `user_name` VARCHAR(255) NOT NULL, + `user_email` VARCHAR(255) NOT NULL, + `user_password` VARCHAR(255) NOT NULL, + `role` VARCHAR(45) NOT NULL, + PRIMARY KEY (`UUID_User`)) + ENGINE = InnoDB; + """; + + String settingsTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`Settings` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Settings` ( + `UUID_user` CHAR(36) NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `language` VARCHAR(45) NOT NULL, + `lightmode` TINYINT NOT NULL, + PRIMARY KEY (`UUID_user`), + INDEX `fk_Settings_User1_idx` (`UUID_user` ASC) VISIBLE, + CONSTRAINT `fk_Settings_User1` + FOREIGN KEY (`UUID_user`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + + String messagesTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`Messages` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Messages` ( + `UUID_message` CHAR(36) NOT NULL, + `message_title` VARCHAR(255) NOT NULL, + `message_content` VARCHAR(255) NOT NULL, + `message_date` DATE NOT NULL, + `sender_user_id` CHAR(36) NULL, + `sender_charity_id` CHAR(36) NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_message`), + INDEX `fk_Messages_User1_idx` (`sender_user_id` ASC) VISIBLE, + INDEX `fk_Messages_Charities1_idx` (`sender_charity_id` ASC) VISIBLE, + INDEX `fk_Messages_User2_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Messages_User1` + FOREIGN KEY (`sender_user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_Charities1` + FOREIGN KEY (`sender_charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Messages_User2` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + + String feedbackTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`Feedback` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Feedback` ( + `UUID_feedback` CHAR(36) NOT NULL, + `feedback_comment` VARCHAR(255) NOT NULL, + `feedback_date` DATE NOT NULL, + `isAnonymous` TINYINT NOT NULL, + `charity_id` CHAR(36) NOT NULL, + `user_id` CHAR(36) NOT NULL, + PRIMARY KEY (`UUID_feedback`), + INDEX `fk_Feedback_Charities1_idx` (`charity_id` ASC) VISIBLE, + INDEX `fk_Feedback_User1_idx` (`user_id` ASC) VISIBLE, + CONSTRAINT `fk_Feedback_Charities1` + FOREIGN KEY (`charity_id`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Feedback_User1` + FOREIGN KEY (`user_id`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + String categoriesTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`Categories` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Categories` ( + `category_id` INT NOT NULL AUTO_INCREMENT, + `category` VARCHAR(255) NOT NULL, + PRIMARY KEY (`category_id`), + UNIQUE (`category`) + ) + ENGINE = InnoDB; + """; + + String charityCategoriesTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`Charity_Categories` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`Charity_Categories` ( + `Categories_category_id` INT NOT NULL, + `Charities_UUID_charities` CHAR(36) NOT NULL, + PRIMARY KEY (`Categories_category_id`, `Charities_UUID_charities`), + INDEX `fk_Categories_has_Charities_Charities1_idx` (`Charities_UUID_charities` ASC) VISIBLE, + INDEX `fk_Categories_has_Charities_Categories1_idx` (`Categories_category_id` ASC) VISIBLE, + CONSTRAINT `fk_Categories_has_Charities_Categories1` + FOREIGN KEY (`Categories_category_id`) + REFERENCES `apbaluna`.`Categories` (`category_id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Categories_has_Charities_Charities1` + FOREIGN KEY (`Charities_UUID_charities`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE CASCADE + ON UPDATE CASCADE) + ENGINE = InnoDB; + """; + + String charityUserTable = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`CharityUsers` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`CharityUsers` ( + `TheCharity` CHAR(36) NOT NULL, + `CharityUserId` CHAR(36) NOT NULL, + PRIMARY KEY (`TheCharity`, `CharityUserId`), + INDEX `fk_Charities_has_User_User1_idx` (`CharityUserId` ASC) VISIBLE, + INDEX `fk_Charities_has_User_Charities1_idx` (`TheCharity` ASC) VISIBLE, + CONSTRAINT `fk_Charities_has_User_Charities1` + FOREIGN KEY (`TheCharity`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Charities_has_User_User1` + FOREIGN KEY (`CharityUserId`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + String charityVanityTable = + """ + CREATE TABLE IF NOT EXISTS `apbaluna`.`CharityVanity` ( + `UUID_charity` CHAR(36) NOT NULL, + `charity_name` VARCHAR(255) NOT NULL, + `charity_link` VARCHAR(255) NOT NULL, + `description` TEXT NULL, + `logoURL` TEXT NULL, + `key_values` TEXT NULL, + `logoBLOB` MEDIUMBLOB NULL, + CONSTRAINT `unique_UUID_charity` UNIQUE (`UUID_charity`), + INDEX `fk_CharityVanity_Charities1_idx` (`UUID_charity` ASC) VISIBLE, + CONSTRAINT `fk_CharityVanity_Charities1` + FOREIGN KEY (`UUID_charity`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE CASCADE + ON UPDATE CASCADE) + ENGINE = InnoDB; + """; + + String userHasFavourites = + """ + -- ----------------------------------------------------- + -- Table `apbaluna`.`User_has_favourites` + -- ----------------------------------------------------- + CREATE TABLE IF NOT EXISTS `apbaluna`.`User_has_favourites` ( + `Favourite_Charity` CHAR(36) NOT NULL, + `Favourer` CHAR(36) NOT NULL, + PRIMARY KEY (`Favourite_Charity`, `Favourer`), + INDEX `fk_Charities_has_User_User2_idx` (`Favourer` ASC) VISIBLE, + INDEX `fk_Charities_has_User_Charities2_idx` (`Favourite_Charity` ASC) VISIBLE, + CONSTRAINT `fk_Charities_has_User_Charities2` + FOREIGN KEY (`Favourite_Charity`) + REFERENCES `apbaluna`.`Charities` (`UUID_charities`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Charities_has_User_User2` + FOREIGN KEY (`Favourer`) + REFERENCES `apbaluna`.`User` (`UUID_User`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + """; + + try (Connection conn = connection.getMySqlConnection(); + Statement s = conn.createStatement()) { + + s.execute(charitiesTable); + s.execute(userTable); + s.execute(donationsTable); + s.execute(settingsTable); + s.execute(messagesTable); + s.execute(feedbackTable); + s.execute(categoriesTable); + s.execute(charityCategoriesTable); + s.execute(charityUserTable); + s.execute(charityVanityTable); + s.execute(userHasFavourites); + + } catch (SQLException e) { + e.printStackTrace(); + throw new RuntimeException("Error creating table."); + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java index d97d9968..4516abba 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java @@ -20,8 +20,8 @@ public class Charity { /* Name of the charity */ private String name; - /* Description of the charity's mission and activities */ - private String description; + /* URL of the charity */ + private String url; /* Is the charity verified? */ private String status; @@ -29,11 +29,40 @@ public class Charity { private boolean is_pre_approved; /* Category for the charity */ - private String category; + private List category; + + /* Description for the charity */ + private String description; + + /* URL for the logo of the charity */ + private String logoURL; + + /* Key values for the charity */ + private String keyValues; /* List that contains the charity's Feedbacks */ private List feedbacks; + /* Bytecode for the charity logo */ + private byte[] logoBlob; + + /** + * Minimal contructor JUST FOR DONATIONSSELECT. Just cause donation object needs to only contain + * information about receiver {@code Chairty } and donator {@code User}, and not necessarily Urls, + * logos, and etc. + * + * @param uuid from DonationSelect + * @param org_number matches from DonationSelect + * @param is_pre_approved name matches from DonationSelect + * @param status name matches from DonationSelect + */ + public Charity(String uuid, String org_number, Boolean is_pre_approved, String status) { + this.UUID = java.util.UUID.fromString(uuid); + this.org_number = org_number.replaceAll("\\s", ""); + this.is_pre_approved = is_pre_approved; + this.status = status; + } + /** * Contructor for creating a new charity. Taylored to match data given from Api. Other attributes * will just be initialized as empty @@ -45,19 +74,21 @@ public class Charity { */ public Charity( String org_number, String link, String name, boolean is_pre_approved, String status) { - this.UUID = java.util.UUID.randomUUID(); + UUID stableId = UUID.nameUUIDFromBytes((org_number + link + name).getBytes()); + this.UUID = stableId; this.org_number = org_number.replaceAll("\\s", ""); this.name = name; - this.description = "Les mer her: " + link; + this.url = link; this.is_pre_approved = is_pre_approved; this.status = status; this.feedbacks = new ArrayList<>(); - this.category = ""; + this.category = new ArrayList<>(); } /** - * Contructor for creating a new charity. Taylored to match data given from DATABASE. Other - * attributes will just be initialized as empty + * Contructor for creating a new charity. Taylored to match data given from DATABASE. Expects + * paramaters that will fill all attributes. EXECPT for feedbacks and categories (which is done + * right after). * * @param org_number matches from innsamlingkontrollen * @param name matches from innsamlingkontrollen @@ -67,18 +98,26 @@ public Charity( public Charity( String uuid, String org_number, - String link, String name, + String url, + String status, boolean is_pre_approved, - String status) { + String description, + String logoURL, + String keyValues, + byte[] logblob) { this.UUID = UUID.fromString(uuid); this.org_number = org_number.replaceAll("\\s", ""); this.name = name; - this.description = link; + this.url = url; this.is_pre_approved = is_pre_approved; this.status = status; + this.category = new ArrayList<>(); + this.description = description; + this.logoURL = logoURL; + this.keyValues = keyValues; this.feedbacks = new ArrayList<>(); - this.category = ""; + this.logoBlob = logblob; } /** Getters for the charity's attributes. */ @@ -102,7 +141,7 @@ public List getFeedbacks() { return feedbacks; } - public String getCategory() { + public List getCategory() { return category; } @@ -110,8 +149,29 @@ public String getName() { return name; } + public String getURL() { + return this.url; + } + public String getDescription() { - return description; + return this.description; + } + + public String getLogoURL() { + return this.logoURL; + } + + public String getKeyValues() { + return this.keyValues; + } + + public byte[] getLogoBlob() { + return this.logoBlob; + } + + /** Setter for new name */ + public void setName(String name) { + this.name = name; } /** Setter for verification status. This one sets the charity as verified. */ @@ -123,4 +183,38 @@ public void setVerified() { public void setUnverified() { this.status = "Veto"; } + + /** Setter for categories. */ + public void setCategory(List category) { + this.category = category; + } + + /** Setter for description. */ + public void setDescription(String description) { + this.description = description; + } + + /** Setter for the URL of the charity's logo. */ + public void setLogoURL(String url) { + this.logoURL = url; + } + + /** Setter for the charity's key values. */ + public void setKeyValues(String values) { + this.keyValues = values; + } + + /** Setter for the charity's logo Blob. */ + public void setLogoBlob(byte[] logoBlob) { + this.logoBlob = logoBlob; + } + + /** Setter for setting feedbacks */ + public void setFeedbacks(ArrayList feedbacks) { + this.feedbacks = feedbacks; + } + + public void setUUIDFromString(String uuid) { + this.UUID = java.util.UUID.fromString(uuid); + } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java index 64d87331..c058688a 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java @@ -6,7 +6,7 @@ public class Donation { /* UUID for uniquely identifying each donation */ - private UUID charityId; + private UUID donationID; /* Ammount of money donated */ private double amount; @@ -33,7 +33,7 @@ public class Donation { * @param donor */ public Donation(double amount, LocalDate date, Charity charity, User donor) { - this.charityId = UUID.randomUUID(); + this.donationID = UUID.randomUUID(); this.amount = amount; this.date = date; this.charity = charity; @@ -42,21 +42,28 @@ public Donation(double amount, LocalDate date, Charity charity, User donor) { } /** - * Constructor for creating a new donation. Taylored for getting info FROM DATABASE. NEEDS TO BE - * CHANGED in phase 3. + * Constructor for creating a donation reed from the database. * - * @param amount - * @param date - * @param charity - * @param uuid + * @param donationId the stored UUID string for this donation; must not be {@code null} + * @param amount the donated amount + * @param date the date the donation was made; must not be {@code null} + * @param charity the receiving charity; must not be {@code null} + * @param donor the donating user, or {@code null} if anonymous + * @param isAnonymous whether the donation was recorded as anonymous */ - public Donation(String uuid, double amount, LocalDate date, Charity charity) { - this.charityId = UUID.fromString(uuid); + public Donation( + String donationId, + double amount, + LocalDate date, + Charity charity, + User donor, + boolean isAnonymous) { + this.donationID = UUID.fromString(donationId); this.amount = amount; this.date = date; this.charity = charity; - this.donor = null; - this.isAnonymous = true; + this.donor = donor; + this.isAnonymous = isAnonymous; } /* Getters for the donation's attributes */ @@ -65,7 +72,11 @@ public boolean isAnonymous() { } public UUID getCharityId() { - return charityId; + return charity.getUUID(); + } + + public UUID getDonationID() { + return donationID; } public double getAmount() { diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Feedback.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Feedback.java index 490c47e6..6e78c3b2 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Feedback.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Feedback.java @@ -1,6 +1,6 @@ package ntnu.systemutvikling.team6.models; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.util.UUID; import ntnu.systemutvikling.team6.models.user.User; @@ -15,13 +15,13 @@ public class Feedback { private String comment; /* The date and time when the feedback was given */ - private LocalDateTime date; + private LocalDate date; /* Is the feedback given anonymously? */ private boolean isAnonymous; /** - * Constructor for creating a new feedback. + * Constructor for creating a new feedback now. * * @param user The user who gives the feedback. * @param comment The content of the feedback. @@ -30,7 +30,22 @@ public Feedback(User user, String comment) { this.feedbackId = UUID.randomUUID(); this.user = user; this.comment = comment; - this.date = LocalDateTime.now(); + this.date = LocalDate.now(); + this.isAnonymous = user.getSettings().isAnonymous(); + } + + /** + * Constructor for creating a new feedback, based on making a feedback previously made. + * + * @param user The user who gives the feedback. + * @param comment The content of the feedback. + * @param feedback_date The content of the feedback. + */ + public Feedback(String feedback_id, User user, String feedback_comment, LocalDate feedback_date) { + this.feedbackId = UUID.fromString(feedback_id); + this.user = user; + this.comment = feedback_comment; + this.date = feedback_date; this.isAnonymous = user.getSettings().isAnonymous(); } @@ -48,7 +63,7 @@ public String getComment() { return comment; } - public LocalDateTime getDate() { + public LocalDate getDate() { return date; } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/UserRegistry.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/UserRegistry.java deleted file mode 100644 index 514cbec1..00000000 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/UserRegistry.java +++ /dev/null @@ -1,3 +0,0 @@ -package ntnu.systemutvikling.team6.models; - -public class UserRegistry {} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/CharityRegistry.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/CharityRegistry.java similarity index 93% rename from helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/CharityRegistry.java rename to helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/CharityRegistry.java index 962b8338..c6aabbdd 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/CharityRegistry.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/CharityRegistry.java @@ -1,6 +1,7 @@ -package ntnu.systemutvikling.team6.models; +package ntnu.systemutvikling.team6.models.registry; import java.util.*; +import ntnu.systemutvikling.team6.models.Charity; public class CharityRegistry { private final List charities; diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/DonationRegistry.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/DonationRegistry.java similarity index 81% rename from helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/DonationRegistry.java rename to helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/DonationRegistry.java index b06009dd..d132a710 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/DonationRegistry.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/DonationRegistry.java @@ -1,6 +1,7 @@ -package ntnu.systemutvikling.team6.models; +package ntnu.systemutvikling.team6.models.registry; import java.util.*; +import ntnu.systemutvikling.team6.models.Donation; public class DonationRegistry { private final List donations; @@ -18,7 +19,7 @@ public Optional findDonationById(UUID donationId) { throw new IllegalArgumentException("DonationId can not be null."); } return donations.stream() - .filter(donations -> donationId.equals(donations.getCharityId())) + .filter(donations -> donationId.equals(donations.getDonationID())) .findFirst(); } @@ -33,6 +34,6 @@ public boolean removeDonation(UUID donationId) { if (donationId == null) { throw new IllegalArgumentException("DonationId can not be null."); } - return donations.removeIf(donation -> donationId.equals(donation.getCharityId())); + return donations.removeIf(donation -> donationId.equals(donation.getDonationID())); } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/UserRegistry.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/UserRegistry.java new file mode 100644 index 00000000..7aa85fb3 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/registry/UserRegistry.java @@ -0,0 +1,37 @@ +package ntnu.systemutvikling.team6.models.registry; + +import java.util.*; +import ntnu.systemutvikling.team6.models.user.User; + +public class UserRegistry { + private final List Users; + + public UserRegistry() { + this.Users = new ArrayList<>(); + } + + public List getAllUsers() { + return Collections.unmodifiableList(Users); + } + + public Optional findUserById(UUID userUUID) { + if (userUUID == null) { + throw new IllegalArgumentException("DonationId can not be null."); + } + return Users.stream().filter(u -> userUUID.equals(u.getId())).findFirst(); + } + + public void addUser(User user) { + if (user == null) { + throw new IllegalArgumentException("Donation can not be null."); + } + Users.add(user); + } + + public boolean removeUserByUUID(UUID userUUID) { + if (userUUID == null) { + throw new IllegalArgumentException("DonationId can not be null."); + } + return Users.removeIf(user -> userUUID.equals(user.getId())); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Language.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Language.java index c568ede3..cbd66cf4 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Language.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Language.java @@ -6,5 +6,6 @@ * @author Robin Strand Prestmo */ public enum Language { + NORWEGIAN, ENGLISH } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Message.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Message.java index b70ece1b..ad2370c2 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Message.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Message.java @@ -1,7 +1,8 @@ package ntnu.systemutvikling.team6.models.user; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.util.UUID; +import ntnu.systemutvikling.team6.models.Charity; // Enhetstester mangler @@ -13,26 +14,57 @@ public class Message { private final UUID id; private final String title; - private final String from; + private final Charity fromCharity; private final String content; - private final LocalDateTime timeAndDate; + private final LocalDate timeAndDate; /** - * Creates a message with a unique identifier. The message includes a title, a string who it's + * Creates a message with a unique identifier. The message includes a title, the Charity who it's * from, content and the time and date. * * @param title the title of the message - * @param from who the message is from + * @param charity who the message is from + * @param content the content of the message + * @throws IllegalArgumentException if title, from or content is null or blank. + */ + public Message(String title, Charity charity, String content) { + + if (title == null || title.isBlank()) { + throw new IllegalArgumentException("Title cannot be null or blank."); + } + + if (charity == null) { + throw new IllegalArgumentException("From cannot be null or blank."); + } + + if (content == null || content.isBlank()) { + throw new IllegalArgumentException("Content cannot be null or blank."); + } + + this.id = UUID.randomUUID(); + this.title = title; + this.fromCharity = charity; + this.content = content; + this.timeAndDate = LocalDate.now(); + } + + /** + * Creates a message with a unique identifier. The message includes a title, a string who it's + * from, content and the time and date. This one creates a message that has been created before. + * + * @param title the title of the message + * @param charity who the message is from * @param content the content of the message + * @param date date of when the message was created * @throws IllegalArgumentException if title, from or content is null or blank. */ - public Message(String title, String from, String content) { + public Message(String title, Charity charity, String content, LocalDate date) { if (title == null || title.isBlank()) { throw new IllegalArgumentException("Title cannot be null or blank."); } - if (from == null || from.isBlank()) { + if (charity == null) { throw new IllegalArgumentException("From cannot be null or blank."); } @@ -40,11 +72,15 @@ public Message(String title, String from, String content) { throw new IllegalArgumentException("Content cannot be null or blank."); } + if (date == null) { + throw new IllegalArgumentException("Content cannot be null or blank."); + } + this.id = UUID.randomUUID(); this.title = title; - this.from = from; + this.fromCharity = charity; this.content = content; - this.timeAndDate = LocalDateTime.now(); + this.timeAndDate = date; } public UUID getId() { @@ -55,15 +91,15 @@ public String getTitle() { return title; } - public String getFrom() { - return from; + public Charity getFrom() { + return fromCharity; } public String getContent() { return content; } - public LocalDateTime getTimeAndDate() { + public LocalDate getTimeAndDate() { return timeAndDate; } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Role.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Role.java index 94e0b228..c68752d6 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Role.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Role.java @@ -8,4 +8,5 @@ public enum Role { NORMAL_USER, CHARITY_USER, + ADMIN, } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Settings.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Settings.java index d8142836..086ddb9a 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Settings.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/Settings.java @@ -8,13 +8,13 @@ * @author Robin Strand Prestmo */ public class Settings { - private boolean lightMode; - private Language language; private boolean anonymous; + private Language language; + private boolean lightMode; /** Sets standard settings. LightMode enabled, language set to English, Anonymous disabled */ public Settings() { - this(true, Language.ENGLISH, false); + this(false, Language.ENGLISH, true); } /** @@ -24,7 +24,7 @@ public Settings() { * @param language choose language * @param anonymous choose if user is anonymous */ - public Settings(boolean lightMode, Language language, boolean anonymous) { + public Settings(boolean anonymous, Language language, boolean lightMode) { if (language == null) { throw new IllegalArgumentException("Language cannot be null"); } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/User.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/User.java index ef590006..2e03c72e 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/User.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/user/User.java @@ -17,18 +17,17 @@ public class User { private static final PasswordHasher passwordHasher = new PasswordHasher(); private final UUID id; - private String name; + private String username; private String email; private String passwordHash; - private final Role role; - private final Settings settings; - private final Inbox inbox; + private Role role; + private Settings settings; + private Inbox inbox; /** * Creates a new user. * - * @param id gives the user a unique identifier with UUID - * @param name the name of the user + * @param username unqiue username used for login * @param email the email of the user * @param password the password for the user * @param role users role @@ -37,9 +36,8 @@ public class User { * @throws IllegalArgumentException if any required argument is invalid. */ public User( - String name, String email, String password, Role role, Settings settings, Inbox inbox) { - - if (name == null || name.isBlank()) { + String username, String email, String password, Role role, Settings settings, Inbox inbox) { + if (username == null || username.isBlank()) { throw new IllegalArgumentException("Name cannot be null or blank."); } @@ -61,7 +59,7 @@ public User( } this.id = UUID.randomUUID(); - this.name = name; + this.username = username; this.email = email; this.passwordHash = passwordHasher.getHashPassword(password); this.role = role; @@ -69,20 +67,63 @@ public User( this.inbox = inbox; } + /** + * Creates a new user taylored for getting info from DATABASE. Settings and inbox can be set on a + * later date throught another method in databaseManager class + * + * @param uuid gives the user a unique identifier with UUID + * @param username the name of the user + * @param email the email of the user + * @param password the password for the user + * @param role users role + * @throws IllegalArgumentException if any required argument is invalid. + */ + public User(String uuid, String username, String email, String password, String role) { + + if (uuid == null || uuid.isBlank()) { + throw new IllegalArgumentException("UUID cannot be null or blank."); + } + + if (username == null || username.isBlank()) { + throw new IllegalArgumentException("Name cannot be null or blank."); + } + + if (email == null || email.isBlank() || !email.contains("@") || !email.contains(".")) { + throw new IllegalArgumentException( + "Email cannot be null or blank," + " and must contain '@' and '.'"); + } + + if (role == null) { + throw new IllegalArgumentException("Role cannot be null"); + } + + this.id = UUID.fromString(uuid); + this.username = username; + this.email = email; + this.passwordHash = password; + this.role = Role.valueOf(role); + this.settings = null; + this.inbox = null; + } + // Add Getters public UUID getId() { return id; } - public String getName() { - return name; + public String getUsername() { + return username; } public String getEmail() { return email; } + public String getPasswordHash() { + return passwordHash; + } + public Role getRole() { return role; } @@ -103,11 +144,11 @@ public Inbox getInbox() { * @param name the new name * @throws IllegalArgumentException if the name is null or blank */ - public void setName(String name) { + public void setUsername(String name) { if (name == null || name.isBlank()) { throw new IllegalArgumentException("Name cannot be null or blank."); } - this.name = name; + this.username = name; } /** @@ -146,4 +187,25 @@ public void setEmail(String email) { public boolean checkPassword(String password) { return passwordHasher.isValidPassword(password, passwordHash); } + + public void setSettings(Settings settings) { + if (settings == null) { + throw new IllegalArgumentException("Settings cannot be null"); + } + this.settings = settings; + } + + public void setInbox(Inbox inbox) { + if (inbox == null) { + throw new IllegalArgumentException("Inbox cannot be null"); + } + this.inbox = inbox; + } + + public void setRole(Role role) { + if (role == null) { + throw new IllegalArgumentException("Inbox cannot be null"); + } + this.role = role; + } } diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java new file mode 100644 index 00000000..e881d424 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java @@ -0,0 +1,110 @@ +package ntnu.systemutvikling.team6.scraper; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; +import ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper; +import ntnu.systemutvikling.team6.scraper.scraperComponents.URLCharityScraper; + +/** + * Orchestrates a full charity data scrape by combining two data sources: + * + *

      + *
    1. The external charity API (via {@link APICharityScraper}), which provides structured data + * such as organisation numbers, approval status, and charity URLs. + *
    2. Individual charity web pages (via {@link URLCharityScraper}), which provide richer + * presentation data such as descriptions, logos, categories, and key values. + *
    + * + *

    This class acts as a facade — callers only need to invoke {@link #getAPIAndURLCharityData()} + * to receive a fully populated {@link CharityRegistry}. + */ +public class FullCharityScrape { + private final APICharityScraper apiScraper; + private final LogoDownloader logoDownloader; + + /** + * Constructs a {@code FullCharityScrape} instance and initialises the {@link APICharityScraper} + * with a new {@link HttpClient}. + * + * @throws URISyntaxException if the API endpoint URI used by {@link APICharityScraper} is + * malformed + */ + public FullCharityScrape() throws URISyntaxException { + HttpClient https = HttpClient.newHttpClient(); + this.apiScraper = new APICharityScraper(https); + this.logoDownloader = new LogoDownloader(); + } + + /** + * Performs a full two-phase scrape and returns a {@link CharityRegistry} populated with all + * available charity data. + * + *

    Phase 1 — API scrape: Calls {@link APICharityScraper#checkConnection()} to verify + * availability, then fetches and parses the JSON payload into a {@link CharityRegistry}. + * + *

    Phase 2 — URL scrape: Iterates over every {@link Charity} in the registry and uses a + * {@link URLCharityScraper} to enrich each entry with its description, logo URL, logo blob, + * categories, and key values scraped from the charity's own web page. + * + *

    If {@link APICharityScraper#checkConnection()} throws an exception, it propagates to the + * caller and {@code null} is returned. If the connection check passes but returns {@code false}, + * {@code null} is also returned. + * + * @return a fully populated {@link CharityRegistry}, or {@code null} if the API is unreachable + * @throws IOException if an I/O error occurs during the API request or URL scraping + * @throws InterruptedException if the HTTP request thread is interrupted + */ + public CharityRegistry getAPIAndURLCharityData() throws IOException, InterruptedException { + try { + if (!apiScraper.checkConnection()) { + throw new RuntimeException("Connection check returned false"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + CharityRegistry charityRegistry = apiScraper.parseJSON(apiScraper.getJSONData()); + int charityCounter = 0; + + for (Charity charity : charityRegistry.getAllCharities()) { + System.out.println(charity.getName()); + } + // Scrapes description, logo, categories, and key values from IK + for (Charity charity : charityRegistry.getAllCharities()) { + charityCounter++; + + System.out.println( + "Scraping charity vanity details: " + + charityCounter + + " of " + + charityRegistry.getAllCharities().size()); + try { + URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); + urlScraper.scrapeCharityPage(); + + charity.setDescription(urlScraper.getDescription()); + charity.setCategory(urlScraper.getCategories()); + charity.setLogoURL(urlScraper.getLogoURL()); + charity.setKeyValues(urlScraper.getKeyValues()); + byte[] logoBlob = LogoDownloader.downloadImageAsBlob(charity.getLogoURL()); + charity.setLogoBlob(logoBlob); + } catch (Exception e) { + throw new RuntimeException( + "Failed to Scrape for: [" + + charityCounter + + "]: " + + charity.getName() + + ": " + + e.getMessage()); + } + } + return charityRegistry; + } + + public APICharityScraper getAPIScraper() { + return this.apiScraper; + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java new file mode 100644 index 00000000..2a871ffb --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java @@ -0,0 +1,54 @@ +package ntnu.systemutvikling.team6.scraper; + +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Facilitates downloading of .png images from the individual charity's page on IK, converting them + * to bytecode (blob), and then back to a .png. + */ +public class LogoDownloader { + + /** + * Downloads a image from the given URL and converts it to a blob. + * + * @param imageUrl the URL of the image + * @return a blob containing the image data + */ + public static byte[] downloadImageAsBlob(String imageUrl) { + if (imageUrl == null || imageUrl.isBlank()) return null; + + try (InputStream in = new URL(imageUrl).openStream()) { + return in.readAllBytes(); + } catch (Exception e) { + System.out.println("Error: Something went wrong when downloading the image."); + return null; + } + } + + /** + * Converts a blob of image data back to a .png image file. + * + * @param imageBytes the blob containing the image data + * @param fileName the filename of the .png image file + */ + public static void convertBlobToPNG(byte[] imageBytes, String fileName) { + if (imageBytes == null) { + return; + } + try { + Path folder = Paths.get("target", "logo"); + Files.createDirectories(folder); + + Path filePath = folder.resolve(fileName + ".png"); + + Files.write(filePath, imageBytes); + + } catch (Exception e) { + System.out.println("Error: Something went wrong when converting blob to png."); + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityData.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.java similarity index 94% rename from helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityData.java rename to helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.java index 10a489d7..35b10d5d 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityData.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityData.java @@ -1,6 +1,6 @@ -package ntnu.systemutvikling.team6.scraper; +package ntnu.systemutvikling.team6.scraper.scraperComponents; -import ntnu.systemutvikling.team6.database.DatabaseManager; +import ntnu.systemutvikling.team6.database.DatabaseSetup; /** * Represents data parsed from the IK API JSON response. Instances are immutable; to update any @@ -9,7 +9,7 @@ *

    Receives data directly from {@link APICharityScraper}. * *

    {@code org_number} should be a unique number, as it is used as a primary key in {@link - * DatabaseManager}. + * DatabaseSetup}. */ public class APICharityData { private final String org_number; diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.java similarity index 93% rename from helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java rename to helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.java index 89422a1a..16be61f7 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/APICharityScraper.java @@ -1,4 +1,4 @@ -package ntnu.systemutvikling.team6.scraper; +package ntnu.systemutvikling.team6.scraper.scraperComponents; import com.google.gson.Gson; import java.io.IOException; @@ -7,7 +7,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import ntnu.systemutvikling.team6.models.Charity; -import ntnu.systemutvikling.team6.models.CharityRegistry; +import ntnu.systemutvikling.team6.models.registry.CharityRegistry; /** * Fetches JSON information from the IK API and parses the JSON into a list of {@link @@ -81,6 +81,9 @@ public CharityRegistry parseJSON(String JSONData) { CharityRegistry charityRegistry = new CharityRegistry(); for (APICharityData apiCharityData : charityData) { + if (apiCharityData.getStatus().equalsIgnoreCase("obs")) { + continue; + } Charity charity = new Charity( apiCharityData.getOrg_number(), diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java new file mode 100644 index 00000000..33b3c529 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java @@ -0,0 +1,290 @@ +package ntnu.systemutvikling.team6.scraper.scraperComponents; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +/** + * Class for scraping the description, URL of the logo, string of categories, and key values of the + * charities registered in IK. + */ +public class URLCharityScraper { + private final String url; + private final WebDriver driver; + private String description; + private String logoURL; + private final List categories; + private final List keyValues; + + /** + * Constructor used for production code. + * + *

    It initializes the lists used for categories and keyValues, as well as defining the + * parameters used for the selenium Chromium-based browser that does the scraping. + * + * @param url the URL for the charity's webpage on IK + */ + public URLCharityScraper(String url) { + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + + ChromeOptions options = new ChromeOptions(); + options.addArguments("--headless=new"); + options.addArguments("--window-size=1920,1080"); + options.addArguments("--disable-gpu"); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + + this.url = url; + this.driver = new ChromeDriver(options); + } + + /** + * Constructor used for testing. + * + *

    It accepts both a url (should ideally be a dud) and a {@link WebDriver} as parameters. The + * WebDriver is passed to make testing easier. + * + * @param url the URL for the charity's webpage on IK (for this constructor it should not be a + * real URL) + * @param driver the {@code WebDriver} object used for scraping + */ + public URLCharityScraper(String url, WebDriver driver) { + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + this.url = url; + this.driver = driver; + } + + /** + * Creates a {@link WebDriverWait} object for halting scraping until the correct pre-conditions + * are met. + * + * @return the {@code WebDriverWait} object to be used in the methods + */ + protected WebDriverWait createWait() { + return new WebDriverWait(driver, Duration.ofSeconds(10)); + } + + /** + * Calls the {@code findElements} method from the {@code WebDriver} object and returns a list of + * the returned {@link WebElement} objects. + * + * @param by a selector for {@code WebElement} objects + * @return a list of found {@code WebElement} objects matching the given selector + */ + public List findElements(By by) { + return driver.findElements(by); + } + + /** + * Calls the {@code findElement} method from the {@code WebDriver} object and returns a list of + * the returned {@code WebElement} objects. + * + * @param by a selector for {@code WebElement} objects + * @return a list of found {@code WebElement} objects matching the given selector + */ + protected WebElement findElement(By by) { + return driver.findElement(by); + } + + /** Quits the driver instance, making it unusable. */ + protected void closeDriver() { + driver.quit(); + } + + /** Scrapes the URL for the paragraphs containing the description of the charity. */ + protected void updateDescription() { + try { + WebDriverWait wait = createWait(); + StringBuilder descriptionString = new StringBuilder(); + + List readMoreLinks = findElements(By.cssSelector("a.read-more")); + + if (!readMoreLinks.isEmpty()) { + WebElement readMore = findElement(By.cssSelector("a.read-more")); + readMore.click(); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + } + + wait.until( + ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information"), 0)); + + // Thread.sleep(5000); + List firstDescription = findElements(By.cssSelector(".information")); + + for (WebElement element : firstDescription) { + if (!element.getText().isBlank()) { + descriptionString.append(element.getText()).append("\n\n"); + } + } + + this.description = descriptionString.toString(); + + } catch (Exception e) { + System.out.println("No description found for " + driver.getCurrentUrl()); + } + } + + /** Scrapes the URL for the image URL of the logo for the charity. */ + void updateLogo() { + try { + WebDriverWait wait = createWait(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + // Thread.sleep(5000); + + WebElement logo = findElement(By.cssSelector(".logo > img")); + this.logoURL = logo.getAttribute("src"); + + } catch (Exception e) { + System.out.println("No logo found for " + driver.getCurrentUrl()); + } + } + + /** Scrapes the URL for the category labels containing the categories for the charity. */ + void updateCategories() { + try { + WebDriverWait wait = createWait(); + + wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".tag-label"))); + // Thread.sleep(5000); + + List elements = findElements(By.cssSelector(".tag-label")); + + for (WebElement element : elements) { + this.categories.add(element.getText()); + } + + } catch (Exception e) { + System.out.println("No categories found for " + driver.getCurrentUrl()); + } + } + + /** + * Scrapes the URL for the statistics of the charity; the percentage collected, the percentage + * that goes to the administration, and the percentage that is put towards the cause. + */ + void updateKeyValues() { + try { + WebDriverWait wait = createWait(); + + String percentage; + WebElement element; + + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath( + "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); + // Thread.sleep(5000); + element = + findElement( + By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); + + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); + + element = + findElement( + By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); + + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath("//li[.//h2[normalize-space()='FormĂĄlsprosent']]//div[@class='graph']"))); + + element = + findElement( + By.xpath("//li[.//h2[normalize-space()='FormĂĄlsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); + } catch (Exception e) { + System.out.println("No key values found for " + driver.getCurrentUrl()); + } + } + + /** Runs all the scraper methods at once, updating the object parameters. */ + public void scrapeCharityPage() { + try { + driver.get(this.url); + updateDescription(); + updateLogo(); + updateCategories(); + updateKeyValues(); + // Thread.sleep(1000); + + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + closeDriver(); + } + } + + /** + * Returns the description of the charity. + * + * @return a String containing the description of the charity. + */ + public String getDescription() { + return description; + } + + /** + * Returns the URL of the logo for the charity. + * + * @return a String containing the URL for the logo of the charity. + */ + public String getLogoURL() { + return logoURL; + } + + /** + * Returns a String of the categories for the charity with ',' as a delimiter. + * + * @return a String of strings containing the categories for the charity + */ + public List getCategories() { + /* + StringBuilder categoriesString = new StringBuilder(); + + for (int i = 0; i < this.categories.size(); i++) { + categoriesString.append(this.categories.get(i)); + if (i < this.categories.size() - 1) { + categoriesString.append(","); + } + } + */ + return categories; + } + + /** + * Returns a String of the key value percentages for the charity with ':' as a delimiter, verified + * by IK. + * + * @return a String of the key values for the charity- + */ + public String getKeyValues() { + StringBuilder keyValuesString = new StringBuilder(); + + for (int i = 0; i < this.keyValues.size(); i++) { + keyValuesString.append(this.keyValues.get(i)); + if (i < this.keyValues.size() - 1) { + keyValuesString.append(":"); + } + } + return keyValuesString.toString(); + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java new file mode 100644 index 00000000..e49b8ce6 --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java @@ -0,0 +1,224 @@ +package ntnu.systemutvikling.team6.service; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.UUID; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; + +public class APIToDatabaseService { + private final DatabaseConnection connection; + + /** + * Contractor for APIToDatabaseService. It uses a DatabaseConnection object that contains a + * connection credentials. + * + * @param connection + */ + public APIToDatabaseService(DatabaseConnection connection) { + this.connection = connection; + } + + /** + * This method is used to verify the integrity of the data in the {@code charities} table and to + * update it based on the data retrieved from the IK API and the charity's URL. The param + * charities are retrieved from the IK API through the APICharityData class. Called in initialize + * method in HmHApplication.java, which is the main class of the application, to ensure that the + * data is up to date when the application starts. Uses a temp table to ensure that the data in + * the database is consistent with the data from the API. + * + *

    Uses a URLScraper object to get data not contained in the API, and static methods from + * LogoDownloader to get the charity's logo as a blob. + * + * @param charities a list of {@code Charity} objects to add to the database + */ + public void addAPIDataToTable(List charities) { + Connection conn = null; + try { + conn = connection.getMySqlConnection(); + conn.setAutoCommit(false); + + String sql1 = + """ + INSERT INTO Charities (UUID_charities, org_number, pre_approved, status) + VALUES (?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + pre_approved = VALUES(pre_approved), + status = VALUES(status); + """; + + String sql2 = + """ + INSERT INTO CharityVanity (UUID_charity, charity_name, charity_link, description, logoURL, key_values, logoBlob) + VALUES (?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + charity_name = VALUES(charity_name), + charity_link = VALUES(charity_link), + description = VALUES(description), + logoURL = VALUES(logoURL), + key_values = VALUES(key_values), + logoBlob = VALUES(logoBlob); + """; + + String sql3 = "INSERT IGNORE INTO Categories (category) VALUES (?)"; + + String sql4 = "SELECT category_id FROM Categories WHERE category = ?"; + + String sql5 = + """ + INSERT IGNORE INTO Charity_Categories (Categories_category_id, Charities_UUID_charities) + VALUES (?, ?) + """; + + try (PreparedStatement ps1 = conn.prepareStatement(sql1); + PreparedStatement ps2 = conn.prepareStatement(sql2); + PreparedStatement ps3 = conn.prepareStatement(sql3); + PreparedStatement ps4 = conn.prepareStatement(sql4); + PreparedStatement ps5 = conn.prepareStatement(sql5)) { + + for (Charity charity : charities) { + String uuid; + if (charity.getUUID() == null) { + + uuid = + UUID.nameUUIDFromBytes( + (charity.getOrg_number() + charity.getURL() + charity.getName()).getBytes()) + .toString(); + charity.setUUIDFromString(uuid); + System.out.println("API object doesn't have UUID, assigning stable UUID"); + } else { + uuid = charity.getUUID().toString(); + } + + ps1.setString(1, uuid); + ps1.setString(2, charity.getOrg_number().replaceAll("\\s", "")); + ps1.setBoolean(3, charity.getPreApproved()); + ps1.setString(4, charity.getStatus()); + ps1.executeUpdate(); + + ps2.setString(1, uuid); + ps2.setString(2, charity.getName()); + ps2.setString(3, charity.getURL()); + ps2.setString(4, charity.getDescription()); + ps2.setString(5, charity.getLogoURL()); + ps2.setString(6, charity.getKeyValues()); + ps2.setBytes(7, charity.getLogoBlob()); + ps2.executeUpdate(); + + if (charity.getCategory() != null) { + for (String categoryRaw : charity.getCategory()) { + if (categoryRaw == null) continue; + + String category = categoryRaw.toLowerCase().trim(); + + if (category.isEmpty()) continue; + + ps3.setString(1, category); + ps3.executeUpdate(); + + ps4.setString(1, category); + + try (ResultSet rs = ps4.executeQuery()) { + if (rs.next()) { + int categoryId = rs.getInt("category_id"); + + ps5.setInt(1, categoryId); + ps5.setString(2, uuid); + ps5.executeUpdate(); + } + } + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + + // Integrity Check + String createTemp = + """ + CREATE TEMPORARY TABLE temp_api_charities ( + org_number VARCHAR(255) PRIMARY KEY + ) + """; + try (PreparedStatement ps = conn.prepareStatement(createTemp)) { + ps.execute(); + } + + String insertTemp = "INSERT IGNORE INTO temp_api_charities (org_number) VALUES (?)"; + try (PreparedStatement ps = conn.prepareStatement(insertTemp)) { + for (Charity charity : charities) { + ps.setString(1, charity.getOrg_number().replaceAll("\\s", "")); + ps.addBatch(); + } + ps.executeBatch(); + } + + String deleteSql = + """ + DELETE FROM Charities c + WHERE NOT EXISTS ( + SELECT 1 FROM temp_api_charities t + WHERE t.org_number = c.org_number + ) + AND NOT EXISTS ( + SELECT 1 FROM Donations d WHERE d.charity_id = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM Feedback f WHERE f.charity_id = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM CharityVanity cv WHERE cv.UUID_charity = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM CharityUsers cu WHERE cu.TheCharity = c.UUID_charities + ); + """; + + String deleteUnusedCategoriesSql = + """ + + DELETE FROM Categories c + WHERE NOT EXISTS ( + SELECT 1 + FROM Charity_Categories cc + WHERE cc.Categories_category_id = c.category_id + ); + """; + + try (PreparedStatement ps1 = conn.prepareStatement(deleteSql); + PreparedStatement ps2 = conn.prepareStatement(deleteUnusedCategoriesSql)) { + + ps1.executeUpdate(); + ps2.executeUpdate(); + } + + conn.commit(); + + } catch (SQLException e) { + if (conn != null) { + try { + conn.rollback(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + e.printStackTrace(); + throw new RuntimeException("ERROR: Something went wrong during updating charities table."); + } finally { + if (conn != null) { + try { + conn.setAutoCommit(true); + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/AuthenticationService.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/AuthenticationService.java index 8b137891..639e0862 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/AuthenticationService.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/AuthenticationService.java @@ -1 +1,122 @@ +package ntnu.systemutvikling.team6.service; +import ntnu.systemutvikling.team6.database.DAO.CharityUserDAO; +import ntnu.systemutvikling.team6.database.DAO.UserDAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.user.Inbox; +import ntnu.systemutvikling.team6.models.user.Role; +import ntnu.systemutvikling.team6.models.user.Settings; +import ntnu.systemutvikling.team6.models.user.User; + +/** + * Service class responsible for handling user authentication operations, including login, + * registration, and logout functionality. + * + *

    Maintains the state of the currently authenticated user throughout the session. + */ +public class AuthenticationService { + /** Handles read operations for user data from the database. */ + private final UserDAO userDataAcsessObject; + + /** Handles write operations for user data to the database. */ + + /** The currently authenticated user, or {@code null} if no user is logged in. */ + private User currentUser; + + private Charity isCharityUser; + + /** + * Constructs an {@code AuthenticationService} with the specified data access objects. + * + * @param userDAO the data reader used to query user information from the database + */ + public AuthenticationService(UserDAO userDAO) { + this.userDataAcsessObject = userDAO; + } + + /** + * Attempts to authenticate a user with the given credentials. + * + *

    If a matching user is found in the database, they are set as the current user and the method + * returns {@code true}. + * + * @param email the username of the user attempting to log in + * @param password the password of the user attempting to log in + * @return {@code true} if authentication was successful; {@code false} otherwise + */ + public boolean login(String email, String password) { + User user = userDataAcsessObject.getUserFromDBEmailAndPassword(email, password); + + if (user != null) { + currentUser = user; + CharityUserDAO charityUserDAO = new CharityUserDAO(new DatabaseConnection()); + isCharityUser = charityUserDAO.getUserCharityUser(currentUser.getId().toString()); + if (isCharityUser != null) { + currentUser.setRole(Role.CHARITY_USER); + } + System.out.println("User gotten"); + return true; + } + + return false; + } + + /** + * Registers a new user account with the provided details. + * + *

    The new user is assigned the {@link Role#NORMAL_USER} role and default {@link Settings} and + * {@link Inbox}. Registration will fail if the username is already taken or if the database + * operation is unsuccessful. On success, the new user is set as the current user. + * + * @param username the unique username for the new account + * @param email the email address associated with the new account + * @param password the password for the new account + * @return {@code true} if registration was successful; {@code false} if the username is already + * taken or the database operation failed + */ + public boolean register(String username, String email, String password) { + User newUser = + new User(username, email, password, Role.NORMAL_USER, new Settings(), new Inbox()); + + if (userDataAcsessObject.isEmailTaken(email)) { + throw new IllegalArgumentException("Email already taken"); + } + + boolean success = userDataAcsessObject.registerUser(newUser); + + if (success) { + // currentUser = newUser; + // Proceed to login first + return true; + } + return false; + } + + /** Logs out the currently authenticated user by clearing the current user state. */ + public void logout() { + currentUser = null; + } + + /** + * Returns the currently authenticated user. + * + * @return the current {@link User}, or {@code null} if no user is logged in + */ + public User getCurrentUser() { + return currentUser; + } + + /** + * Checks whether a user is currently logged in. + * + * @return {@code true} if a user is authenticated; {@code false} otherwise + */ + public boolean isLoggedin() { + return currentUser != null; + } + + public Charity isCharityUser() { + return isCharityUser; + } +} diff --git a/helpmehelpapplication/src/main/main.iml b/helpmehelpapplication/src/main/main.iml new file mode 100644 index 00000000..908ad4f5 --- /dev/null +++ b/helpmehelpapplication/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/helpmehelpapplication/src/main/resources/fxml/aboutPage.fxml b/helpmehelpapplication/src/main/resources/fxml/aboutPage.fxml index 10e12e81..1d6bbe4b 100644 --- a/helpmehelpapplication/src/main/resources/fxml/aboutPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/aboutPage.fxml @@ -1,10 +1,8 @@ - - @@ -20,560 +18,419 @@ - + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - \ No newline at end of file + diff --git a/helpmehelpapplication/src/main/resources/fxml/available_organizations.fxml b/helpmehelpapplication/src/main/resources/fxml/available_organizations.fxml new file mode 100644 index 00000000..bce73a20 --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/available_organizations.fxml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml index 041b51b0..4c0678c6 100644 --- a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml @@ -6,9 +6,7 @@ - - @@ -23,10 +21,11 @@ - + + @@ -36,77 +35,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - @@ -136,81 +67,89 @@ - + + - + - - - - + + - + - + - + - - + + @@ -219,6 +158,7 @@ + @@ -229,13 +169,16 @@ - - - - - - - + + + @@ -244,10 +187,9 @@ - + - - + @@ -257,20 +199,19 @@ - - + - + - + @@ -279,240 +220,143 @@ - - + + + + + + + + + + - - - + + + - + + + - - - - - - - - - + - - - + + - - + + - - + + - - + + - - + + + + + - - - + + - + + + - - - + + - - - + + - - - - - - - - - - - - - - - - - - - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/components/categoryTag.fxml b/helpmehelpapplication/src/main/resources/fxml/components/categoryTag.fxml new file mode 100644 index 00000000..3e509532 --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/components/categoryTag.fxml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/components/inboxCard.fxml b/helpmehelpapplication/src/main/resources/fxml/components/inboxCard.fxml new file mode 100644 index 00000000..112ef98f --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/components/inboxCard.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/components/interestCard.fxml b/helpmehelpapplication/src/main/resources/fxml/components/interestCard.fxml new file mode 100644 index 00000000..5ffb4967 --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/components/interestCard.fxml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/components/navbar.fxml b/helpmehelpapplication/src/main/resources/fxml/components/navbar.fxml new file mode 100644 index 00000000..30cb898f --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/components/navbar.fxml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/organizationCard.fxml b/helpmehelpapplication/src/main/resources/fxml/components/organizationCard.fxml similarity index 67% rename from helpmehelpapplication/src/main/resources/fxml/organizationCard.fxml rename to helpmehelpapplication/src/main/resources/fxml/components/organizationCard.fxml index 47ddc788..9076186d 100644 --- a/helpmehelpapplication/src/main/resources/fxml/organizationCard.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/components/organizationCard.fxml @@ -5,8 +5,9 @@ + - + @@ -15,20 +16,28 @@ - - + + + + + + + + + + + + + + diff --git a/helpmehelpapplication/src/main/resources/fxml/dashboard.fxml b/helpmehelpapplication/src/main/resources/fxml/dashboard.fxml new file mode 100644 index 00000000..b1b6bbec --- /dev/null +++ b/helpmehelpapplication/src/main/resources/fxml/dashboard.fxml @@ -0,0 +1,584 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + @@ -144,12 +87,24 @@ @@ -160,83 +115,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/helpmehelpapplication/src/main/resources/fxml/frontPage.fxml b/helpmehelpapplication/src/main/resources/fxml/frontPage.fxml index 93ed395c..a564a0b2 100644 --- a/helpmehelpapplication/src/main/resources/fxml/frontPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/frontPage.fxml @@ -21,362 +21,157 @@ - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +