diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..549a938
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.idea/
+*.iml
+target/
+*.class
+*.properties
\ No newline at end of file
diff --git a/banking/pom.xml b/banking/pom.xml
new file mode 100644
index 0000000..e6e1e04
--- /dev/null
+++ b/banking/pom.xml
@@ -0,0 +1,23 @@
+
+
+ 4.0.0
+
+ com.revature
+ banking
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+
+
+
+ org.postgresql
+ postgresql
+ 42.2.12
+
+
+
+
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/BankingApp.java b/banking/src/main/java/com/revature/BankingApp.java
new file mode 100644
index 0000000..34ae888
--- /dev/null
+++ b/banking/src/main/java/com/revature/BankingApp.java
@@ -0,0 +1,23 @@
+package com.revature;
+
+import com.revature.screens.HomeScreen;
+import com.revature.util.AppState;
+
+public class BankingApp {
+
+ private static AppState app =new AppState();
+
+ public static void main(String[] args){
+ while(app.isAppRunning()){
+ app.getRouter().navigate("/home");
+ }
+ }
+
+
+ //convenient to use, also works if we made the object public instead of private
+ public static AppState app(){
+ return app;
+ }
+
+
+}
diff --git a/banking/src/main/java/com/revature/account/Account.java b/banking/src/main/java/com/revature/account/Account.java
new file mode 100644
index 0000000..a0561f7
--- /dev/null
+++ b/banking/src/main/java/com/revature/account/Account.java
@@ -0,0 +1,75 @@
+package com.revature.account;
+
+import com.revature.exceptions.InvalidRequestException;
+
+public class Account {
+
+ public int accountId;
+ private AccountTypes accountType;
+ private double balance;
+
+ public Account(){
+
+ }
+
+ public Account(double balance,AccountTypes accountType){
+ this.balance=balance;
+ this.accountType=accountType;
+ }
+
+ public Account( double balance,AccountTypes accountType,int accountId){
+ this.accountId=accountId;
+ this.accountType=accountType;
+ this.balance=balance;
+ }
+
+ public double deposit(double amount){
+ balance+= amount;
+ return balance;
+ }
+
+ public double withdraw(double amount){
+ if(amount>balance){
+ System.err.println("Insufficient Funds!");
+ System.out.print("current balance: ");
+ return balance;
+
+ }
+ balance-=amount;
+ return balance;
+ }
+
+ public double transfer(double amount){
+ if(amount>balance){
+ System.err.println("Insufficient Funds!");
+ System.out.print("current balance: ");
+ return balance;
+
+ }
+ return amount;
+ }
+
+ public int getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(int accountId) {
+ this.accountId = accountId;
+ }
+
+ public AccountTypes getAccountType() {
+ return accountType;
+ }
+
+ public void setAccountType(AccountTypes accountType) {
+ this.accountType = accountType;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+}
diff --git a/banking/src/main/java/com/revature/account/AccountTypes.java b/banking/src/main/java/com/revature/account/AccountTypes.java
new file mode 100644
index 0000000..647413d
--- /dev/null
+++ b/banking/src/main/java/com/revature/account/AccountTypes.java
@@ -0,0 +1,5 @@
+package com.revature.account;
+
+public enum AccountTypes {
+ CHECKING_ACCOUNT, SAVINGS_ACCOUNT
+}
diff --git a/banking/src/main/java/com/revature/exceptions/AuthenticationException.java b/banking/src/main/java/com/revature/exceptions/AuthenticationException.java
new file mode 100644
index 0000000..76d2028
--- /dev/null
+++ b/banking/src/main/java/com/revature/exceptions/AuthenticationException.java
@@ -0,0 +1,9 @@
+package com.revature.exceptions;
+
+public class AuthenticationException extends RuntimeException {
+
+ public AuthenticationException() {
+ super("Authentication failed!");
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/exceptions/InvalidAccountException.java b/banking/src/main/java/com/revature/exceptions/InvalidAccountException.java
new file mode 100644
index 0000000..19a1093
--- /dev/null
+++ b/banking/src/main/java/com/revature/exceptions/InvalidAccountException.java
@@ -0,0 +1,9 @@
+package com.revature.exceptions;
+
+public class InvalidAccountException extends RuntimeException{
+
+
+ public InvalidAccountException(String message){
+ super(message);
+ }
+}
diff --git a/banking/src/main/java/com/revature/exceptions/InvalidRequestException.java b/banking/src/main/java/com/revature/exceptions/InvalidRequestException.java
new file mode 100644
index 0000000..674c6fe
--- /dev/null
+++ b/banking/src/main/java/com/revature/exceptions/InvalidRequestException.java
@@ -0,0 +1,13 @@
+package com.revature.exceptions;
+
+public class InvalidRequestException extends RuntimeException {
+
+ public InvalidRequestException() {
+ super("Invalid request made!");
+ }
+
+ public InvalidRequestException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/exceptions/ResourcePersistenceException.java b/banking/src/main/java/com/revature/exceptions/ResourcePersistenceException.java
new file mode 100644
index 0000000..9718cf7
--- /dev/null
+++ b/banking/src/main/java/com/revature/exceptions/ResourcePersistenceException.java
@@ -0,0 +1,9 @@
+package com.revature.exceptions;
+
+public class ResourcePersistenceException extends RuntimeException {
+
+ public ResourcePersistenceException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/models/AppUser.java b/banking/src/main/java/com/revature/models/AppUser.java
new file mode 100644
index 0000000..cd5f314
--- /dev/null
+++ b/banking/src/main/java/com/revature/models/AppUser.java
@@ -0,0 +1,117 @@
+package com.revature.models;
+
+import java.util.Objects;
+
+public class AppUser {
+
+ private int id;
+ private String firstName;
+ private String lastName;
+ private String username;
+ private String password;
+ private UserRole userRole;
+
+ public AppUser(){
+ super();
+ }
+
+ // constructor without id and userRole because people dont sign in with an id and role
+ public AppUser(String firstName, String lastName, String username, String password) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.username = username;
+ this.password = password;
+ }
+
+ //constructor with all properties
+ public AppUser(int id, String firstName, String lastName, String username, String password, UserRole userRole) {
+ this(firstName, lastName, username, password);
+ this.id = id;
+ this.userRole = userRole;
+ }
+
+ //Setters and getters to set and obtain information from the database
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public UserRole getUserRole() {
+ return userRole;
+ }
+
+ public void setUserRole(UserRole userRole) {
+ this.userRole = userRole;
+ }
+
+ //to compare values in objects
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AppUser appUser = (AppUser) o;
+ return id == appUser.id &&
+ Objects.equals(firstName, appUser.firstName) &&
+ Objects.equals(lastName, appUser.lastName) &&
+ Objects.equals(username, appUser.username) &&
+ Objects.equals(password, appUser.password) &&
+ userRole == appUser.userRole;
+
+ }
+
+ // facilitates hash structures like a Map
+ public int hashCode() {
+ return Objects.hash(id,firstName,lastName,username,password,userRole);
+ }
+
+ //returns a given value into string format
+ @Override
+ public String toString() {
+ return "AppUser{" +
+ "id=" + id +
+ ", firstName='" + firstName + '\'' +
+ ", lastName='" + lastName + '\'' +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", userRole=" + userRole +
+ '}';
+ }
+
+
+}
diff --git a/banking/src/main/java/com/revature/models/UserRole.java b/banking/src/main/java/com/revature/models/UserRole.java
new file mode 100644
index 0000000..9890ca5
--- /dev/null
+++ b/banking/src/main/java/com/revature/models/UserRole.java
@@ -0,0 +1,5 @@
+package com.revature.models;
+
+public enum UserRole {
+ ADMIN,EMPLOYEES,BASIC_USER
+}
diff --git a/banking/src/main/java/com/revature/repo/AccountRepository.java b/banking/src/main/java/com/revature/repo/AccountRepository.java
new file mode 100644
index 0000000..3b93c4b
--- /dev/null
+++ b/banking/src/main/java/com/revature/repo/AccountRepository.java
@@ -0,0 +1,129 @@
+package com.revature.repo;
+
+import com.revature.account.Account;
+import com.revature.account.AccountTypes;
+import com.revature.models.AppUser;
+import com.revature.util.ConnectionFactory;
+import com.revature.util.LinkedList;
+
+import java.sql.*;
+
+import static com.revature.BankingApp.app;
+
+public class AccountRepository implements CrudRepository{
+
+ private final String base = "SELECT * " +
+ "FROM balance ba " +
+ "JOIN account_type ac " +
+ "USING (account_typeId) ";
+
+ @Override
+ public void save(Account newObj) {
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = "INSERT INTO balance (account_balance, account_typeId, user_id) " +
+ "VALUES (?, ?, ?)";
+
+ PreparedStatement pstmt = conn.prepareStatement(sql, new String[] {"account_balanceid"});
+ pstmt.setDouble(1, newObj.getBalance());
+ pstmt.setInt(2, newObj.getAccountType().ordinal() + 1);
+ pstmt.setInt(3,app().getCurrentSession().getSessionUser().getId());
+
+ int rowsInserted = pstmt.executeUpdate();
+
+ if (rowsInserted != 0) {
+ ResultSet rs = pstmt.getGeneratedKeys();
+ while (rs.next()) {
+ newObj.setAccountId(rs.getInt("account_balanceid"));
+ }
+ }
+
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public LinkedList findAll() {
+ Connection conn = app().getCurrentSession().getConnection();
+ LinkedList account = new LinkedList<>();
+
+ try {
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(base);
+ account = mapResultSet(rs);
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return account;
+ }
+
+ @Override
+ public Account findById(int id) {
+ Account Id=null;
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE account_balanceId = ?";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setInt(1, id);
+
+ ResultSet rs = pstmt.executeQuery();
+ Id = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return Id;
+ }
+
+ @Override
+ public boolean update(Account updatedObj) {
+
+
+ Connection conn = app().getCurrentSession().getConnection();
+
+ try {
+ String sql = "UPDATE balance SET account_balance=? WHERE account_balanceid=? ";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+
+ pstmt.setDouble(1, updatedObj.getBalance());
+ pstmt.setInt(2, updatedObj.getAccountId());
+
+ pstmt.executeUpdate();
+
+
+ }catch(Exception e){
+ System.out.println("failed to deposit or withdraw from account");
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteById(int id) {
+ return false;
+ }
+
+ private LinkedList mapResultSet(ResultSet rs) throws SQLException {
+
+ LinkedList account = new LinkedList<>();
+
+ while(rs.next()) {
+ Account acc = new Account();
+ acc.setAccountId(rs.getInt("account_balanceId"));
+ acc.setAccountType(AccountTypes.valueOf(rs.getString("account_type")));
+ acc.setBalance(rs.getDouble("account_balance"));
+ account.insert(acc);
+ }
+
+ return account;
+
+ }
+}
diff --git a/banking/src/main/java/com/revature/repo/CrudRepository.java b/banking/src/main/java/com/revature/repo/CrudRepository.java
new file mode 100644
index 0000000..71358a1
--- /dev/null
+++ b/banking/src/main/java/com/revature/repo/CrudRepository.java
@@ -0,0 +1,14 @@
+package com.revature.repo;
+
+import com.revature.util.LinkedList;
+import com.revature.util.Set;
+
+public interface CrudRepository {
+
+ void save(T newObj);
+ LinkedList findAll();
+ T findById(int id);
+ boolean update(T updatedObj);
+ boolean deleteById(int id);
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/repo/UserRepository.java b/banking/src/main/java/com/revature/repo/UserRepository.java
new file mode 100644
index 0000000..b599111
--- /dev/null
+++ b/banking/src/main/java/com/revature/repo/UserRepository.java
@@ -0,0 +1,163 @@
+package com.revature.repo;
+
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+import com.revature.repo.CrudRepository;
+import com.revature.util.ConnectionFactory;
+import com.revature.util.LinkedList;
+import com.revature.util.Set;
+
+import java.sql.*;
+
+import static com.revature.BankingApp.app;
+
+public class UserRepository implements CrudRepository {
+
+ private final String base = "SELECT * " +
+ "FROM app_users au " +
+ "JOIN user_roles ur " +
+ "USING (role_id) ";
+
+ public AppUser findUserByUsernameAndPassword(String username, String password) {
+
+ AppUser user = null;
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE username = ? AND password = ? ";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setString(1, username);
+ pstmt.setString(2, password);
+
+ ResultSet rs = pstmt.executeQuery();
+ user = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return user;
+
+ }
+
+ public AppUser findUserByUsername(String username) {
+
+ AppUser user = null;
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE username = ?";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setString(1, username);
+
+ ResultSet rs = pstmt.executeQuery();
+ user = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return user;
+
+ }
+
+ @Override
+ public void save(AppUser newObj) {
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = "INSERT INTO app_users (username, password, first_name, last_name, role_id) " +
+ "VALUES (?, ?, ?, ?, ?)";
+
+ PreparedStatement pstmt = conn.prepareStatement(sql, new String[] {"user_id"});
+ pstmt.setString(1, newObj.getUsername());
+ pstmt.setString(2, newObj.getPassword());
+ pstmt.setString(3, newObj.getFirstName());
+ pstmt.setString(4, newObj.getLastName());
+ pstmt.setInt(5, newObj.getUserRole().ordinal() + 1);
+
+ int rowsInserted = pstmt.executeUpdate();
+
+ if (rowsInserted != 0) {
+ ResultSet rs = pstmt.getGeneratedKeys();
+ while (rs.next()) {
+ newObj.setId(rs.getInt("user_id"));
+ }
+ }
+
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public LinkedList findAll() {
+
+ Connection conn = app().getCurrentSession().getConnection();
+ LinkedList users = new LinkedList<>();
+
+ try {
+
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(base);
+ users = mapResultSet(rs);
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return users;
+ }
+
+ @Override
+ public AppUser findById(int id) {
+
+ AppUser Id=null;
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE user_id = ?";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setInt(1, id);
+
+ ResultSet rs = pstmt.executeQuery();
+ Id = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return Id;
+ }
+
+ @Override
+ public boolean update(AppUser updatedObj) {
+ System.err.println("Not implemented");
+ return false;
+ }
+
+ @Override
+ public boolean deleteById(int id) {
+ System.err.println("Not implemented");
+ return false;
+ }
+
+ private LinkedList mapResultSet(ResultSet rs) throws SQLException {
+
+ LinkedList users = new LinkedList<>();
+
+ while(rs.next()) {
+ AppUser user = new AppUser();
+ user.setId(rs.getInt("user_id"));
+ user.setFirstName(rs.getString("first_name"));
+ user.setLastName(rs.getString("last_name"));
+ user.setUsername(rs.getString("username"));
+ user.setPassword(rs.getString("password"));
+ user.setUserRole(UserRole.valueOf(rs.getString("role_name")));
+ users.insert(user);
+ }
+
+ return users;
+
+ }
+}
diff --git a/banking/src/main/java/com/revature/screens/AccountTypeScreen.java b/banking/src/main/java/com/revature/screens/AccountTypeScreen.java
new file mode 100644
index 0000000..234b1ef
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/AccountTypeScreen.java
@@ -0,0 +1,78 @@
+package com.revature.screens;
+
+import com.revature.account.Account;
+import com.revature.account.AccountTypes;
+import com.revature.repo.AccountRepository;
+import com.revature.services.AccountService;
+
+import static com.revature.BankingApp.app;
+
+public class AccountTypeScreen extends Screen{
+
+ AccountRepository accountRepository= new AccountRepository();
+
+ public AccountTypeScreen(){
+ super("AccountType","/accountType");
+ }
+
+ //render that
+ @Override
+ public void render() {
+
+ Account account=new Account();
+ AccountTypes accountType = null;
+ String myBalance;
+ double initialBalance = 0;
+ System.out.println("+---------------------+");
+ System.out.println("welcome, please select the type of account you would like to create");
+ System.out.println("1) Checking Account");
+ System.out.println("2) Savings Account");
+ System.out.println("3) Exit application");
+
+ System.out.print("> ");
+
+ try {
+ String selection = app().getConsole().readLine();
+
+
+ switch(selection){
+ case "1":
+ System.out.println("Enter in your Starting Balance");
+ myBalance =app().getConsole().readLine();
+ initialBalance=Double.parseDouble(myBalance);
+ account.setBalance(initialBalance);
+ accountType=AccountTypes.CHECKING_ACCOUNT;
+
+ break;
+ case"2":
+ System.out.println("Enter in your Starting Balance");
+ myBalance =app().getConsole().readLine();
+ initialBalance=Double.parseDouble(myBalance);
+ account.setBalance(initialBalance);
+ accountType=AccountTypes.SAVINGS_ACCOUNT;
+
+ break;
+ case"3":
+ System.out.println("Exiting Application");
+ app().setAppRunning(false);
+ break;
+
+ default:
+ System.out.println("Invalid selection");
+ }
+
+
+ account=new Account(initialBalance,accountType);
+
+ accountRepository.save(account);
+
+ app().getRouter().navigate("/dashboard");
+
+ }catch(Exception e){
+ e.printStackTrace();
+ System.err.println("Shutting down application");
+ app().setAppRunning(false);
+
+ }
+ }
+}
diff --git a/banking/src/main/java/com/revature/screens/Dashboard.java b/banking/src/main/java/com/revature/screens/Dashboard.java
new file mode 100644
index 0000000..70383f7
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/Dashboard.java
@@ -0,0 +1,83 @@
+package com.revature.screens;
+
+import com.revature.repo.AccountRepository;
+import com.revature.services.AccountService;
+
+import static com.revature.BankingApp.app;
+
+public class Dashboard extends Screen{
+
+ public Dashboard(){
+ super("Dashboard","/dashboard");
+ }
+
+ @Override
+ public void render() {
+ AccountRepository accountRepository=new AccountRepository();
+ AccountService accountService=new AccountService(accountRepository);
+
+ System.out.println("+---------------------+");
+ System.out.println("Welcome to the Dashboard");
+ System.out.println("1) Open new account");
+ System.out.println("2) deposit to an account");
+ System.out.println("3) withdraw from an account");
+ System.out.println("4) View current balance");
+ System.out.println("5) Exit back to homeScreen");
+
+ try{
+ System.out.print("> ");
+ String userSelection=app().getConsole().readLine();
+ String transaction;
+ double amount;
+ switch(userSelection){
+
+ case "1":
+ System.out.println("Creating new account");
+ app().getRouter().navigate("/accountType");
+ break;
+ case "2":
+
+ System.out.println("Enter transaction amount");
+ System.out.print("> ");
+ transaction=app().getConsole().readLine();
+ amount=Double.parseDouble(transaction);
+
+
+ accountService.Deposit(amount);
+ System.out.println("your deposit of "+amount+" has been added to your account");
+
+ break;
+ case "3":
+
+ System.out.println("Enter transaction amount");
+ transaction=app().getConsole().readLine();
+ amount=Double.parseDouble(transaction);
+ accountService.Withdraw(amount);
+
+ System.out.println("You Withdrew "+ amount+" from your account");
+ break;
+
+ case "4":
+ accountService.viewAccount();
+ break;
+ case "5":
+ System.out.println("Navigating back to HomeScreen");
+ app().getRouter().navigate("/home");
+ break;
+ default:
+ System.out.println("Invalid selection!");
+ }
+
+ System.out.println("what else would you like to do?");
+ app().getRouter().navigate("/dashboard");
+
+
+ }catch(Exception e){
+ e.printStackTrace();
+ System.out.println("would you like to do something else?");
+ app().getRouter().navigate("/dashboard");
+ }
+
+
+ }
+}
diff --git a/banking/src/main/java/com/revature/screens/HomeScreen.java b/banking/src/main/java/com/revature/screens/HomeScreen.java
new file mode 100644
index 0000000..4090de2
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/HomeScreen.java
@@ -0,0 +1,53 @@
+package com.revature.screens;
+import static com.revature.BankingApp.*;
+
+
+//Home Screen of the application, should be able to login/register/exit aplication
+public class HomeScreen extends Screen{
+
+
+ public HomeScreen(){
+ super("HomeScreen","/home");
+ }
+
+ //render that
+ @Override
+ public void render() {
+ System.out.println("welcome to the Banking App!");
+ System.out.println("1) Login");
+ System.out.println("2) Register");
+ System.out.println("3) Exit application");
+
+ System.out.print("> ");
+
+
+ try {
+ String selection = app().getConsole().readLine();
+
+ switch(selection){
+ case "1":
+ System.out.println("Navigating to login screen");
+ app().getRouter().navigate("/login");
+ break;
+ case"2":
+ System.out.println("Navigating to Register screen");
+ app().getRouter().navigate("/register");
+ break;
+ case"3":
+ System.out.println("Exiting Application");
+ app().setAppRunning(false);
+ break;
+
+ default:
+ System.out.println("Invalid selection");
+ }
+
+
+ }catch(Exception e){
+ e.printStackTrace();
+ System.err.println("Shutting down application");
+ app().setAppRunning(false);
+
+ }
+ }
+}
diff --git a/banking/src/main/java/com/revature/screens/LoginScreen.java b/banking/src/main/java/com/revature/screens/LoginScreen.java
new file mode 100644
index 0000000..d365290
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/LoginScreen.java
@@ -0,0 +1,51 @@
+package com.revature.screens;
+
+import com.revature.exceptions.InvalidRequestException;
+import com.revature.models.AppUser;
+import com.revature.services.UserService;
+
+import javax.security.sasl.AuthenticationException;
+
+import static com.revature.BankingApp.app;
+
+public class LoginScreen extends Screen {
+
+ private UserService userService;
+
+ public LoginScreen(UserService userService) {
+ super("LoginScreen", "/login");
+ this.userService = userService;
+ }
+
+ @Override
+ public void render() {
+ String username;
+ String password;
+
+ try {
+
+ System.out.println("+---------------------+");
+ System.out.println("Please provide your login credentials");
+ System.out.print("Username: ");
+ username = app().getConsole().readLine();
+ System.out.print("Password: ");
+ password = app().getConsole().readLine();
+
+ userService.authenticate(username, password);
+
+ if (app().isSessionValid()) {
+ System.out.println("[LOG] - Login successful, navigating to dashboard...");
+ app().getRouter().navigate("/dashboard");
+ }
+
+ } catch (InvalidRequestException | AuthenticationException e) {
+ System.err.println("[INFO] - Invalid login credentials provided!");
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("[SEVERE] - An unexpected exception occurred");
+ System.err.println("[FATAL] - Shutting down application");
+ app().setAppRunning(false);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/screens/RegisterScreen.java b/banking/src/main/java/com/revature/screens/RegisterScreen.java
new file mode 100644
index 0000000..d6e6a2a
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/RegisterScreen.java
@@ -0,0 +1,46 @@
+package com.revature.screens;
+
+import com.revature.models.AppUser;
+import com.revature.services.UserService;
+
+import static com.revature.BankingApp.app;
+
+public class RegisterScreen extends Screen {
+
+ private UserService userService;
+
+ public RegisterScreen(UserService userService) {
+ super("RegisterScreen", "/register");
+ this.userService = userService;
+ }
+
+ @Override
+ public void render() {
+
+ String firstName;
+ String lastName;
+ String username;
+ String password;
+
+ try {
+
+ System.out.println("+---------------------+");
+ System.out.println("Sign up for a new account!");
+ System.out.print("First name: ");
+ firstName = app().getConsole().readLine();
+ System.out.print("Last name: ");
+ lastName = app().getConsole().readLine();
+ System.out.print("Username: ");
+ username = app().getConsole().readLine();
+ System.out.print("Password: ");
+ password = app().getConsole().readLine();
+
+ AppUser newUser = new AppUser(firstName, lastName, username, password);
+
+ userService.register(newUser);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/screens/Screen.java b/banking/src/main/java/com/revature/screens/Screen.java
new file mode 100644
index 0000000..7daf0f4
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/Screen.java
@@ -0,0 +1,22 @@
+package com.revature.screens;
+
+public abstract class Screen {
+ protected String name;
+ protected String route;
+
+ public Screen(String name, String route){
+ this.name=name;
+ this.route=route;
+
+ }
+
+ public String getName(){
+ return name;
+ }
+ public String getRoute(){
+ return route;
+ }
+
+ public abstract void render();
+
+}
diff --git a/banking/src/main/java/com/revature/screens/TransactionScreen.java b/banking/src/main/java/com/revature/screens/TransactionScreen.java
new file mode 100644
index 0000000..f730ad1
--- /dev/null
+++ b/banking/src/main/java/com/revature/screens/TransactionScreen.java
@@ -0,0 +1,64 @@
+package com.revature.screens;
+
+import com.revature.account.Account;
+import com.revature.account.AccountTypes;
+import com.revature.repo.AccountRepository;
+import com.revature.services.AccountService;
+
+import static com.revature.BankingApp.app;
+
+public class TransactionScreen extends Screen{
+ public TransactionScreen() {
+ super("Transaction","/transaction");
+ }
+ AccountRepository accountRepository;
+
+ //render that
+ @Override
+ public void render() {
+
+ Account account;
+ AccountService accountService = null;
+
+ System.out.println("+---------------------+");
+ System.out.println(" Deposit or withdraw from your account");
+ System.out.println("1) Deposit");
+ System.out.println("2) Withdraw");
+ System.out.println("3) Exit application");
+
+ System.out.print("> ");
+
+ try {
+ String selection = app().getConsole().readLine();
+ System.out.println("Enter transaction amount");
+ String transaction=app().getConsole().readLine();
+ double amount=Double.parseDouble(transaction);
+ switch(selection){
+ case "1":
+ accountService.Deposit(amount);
+ System.out.println("your deposit of "+amount+" has been added to your account");
+
+ break;
+ case"2":
+ accountService.Withdraw(amount);
+ System.out.println("You withdrew "+amount+" from your account");
+
+ break;
+ case"3":
+ System.out.println("Exiting Application");
+ app().setAppRunning(false);
+ break;
+
+ default:
+ System.out.println("Invalid selection");
+ }
+
+
+ }catch(Exception e){
+ e.printStackTrace();
+ System.err.println("Shutting down application");
+ app().setAppRunning(false);
+
+ }
+ }
+}
diff --git a/banking/src/main/java/com/revature/services/AccountService.java b/banking/src/main/java/com/revature/services/AccountService.java
new file mode 100644
index 0000000..1298efd
--- /dev/null
+++ b/banking/src/main/java/com/revature/services/AccountService.java
@@ -0,0 +1,62 @@
+package com.revature.services;
+
+import com.revature.account.Account;
+import com.revature.exceptions.InvalidAccountException;
+import com.revature.repo.AccountRepository;
+
+import static com.revature.BankingApp.app;
+
+
+public class AccountService {
+
+ /*
+ withdraw
+ deposit
+ view
+ */
+
+ private AccountRepository accRepo;
+
+ private Account account=new Account();
+
+ public AccountService(AccountRepository accRepo) {
+ this.accRepo = accRepo;
+ }
+
+ public void Deposit(double amount){
+
+ account = accRepo.findById(app().getCurrentSession().getSessionUser().getId());
+ account.setBalance(account.getBalance()+amount);
+ accRepo.update(account);
+ }
+
+ public void Withdraw(double amount){
+ account = accRepo.findById(app().getCurrentSession().getSessionUser().getId());
+ account.setBalance(account.getBalance()-amount);
+ accRepo.update(account);
+
+ }
+
+ public void createAccount(Account account){
+ if(!isValid(account)) {
+ throw new InvalidAccountException("Account not saved");
+ }
+
+
+ accRepo.save(account);
+ }
+
+ public boolean isValid(Account account){
+ return (account.getBalance()>=0);
+ }
+
+ public void viewAccount(){
+ account = accRepo.findById(app().getCurrentSession().getSessionUser().getId());
+ System.out.println("");
+ System.out.println("your current balance is: "+account.getBalance());
+ System.out.println("");
+
+
+ }
+
+}
diff --git a/banking/src/main/java/com/revature/services/UserService.java b/banking/src/main/java/com/revature/services/UserService.java
new file mode 100644
index 0000000..e7addf7
--- /dev/null
+++ b/banking/src/main/java/com/revature/services/UserService.java
@@ -0,0 +1,65 @@
+package com.revature.services;
+
+import com.revature.account.Account;
+import com.revature.exceptions.AuthenticationException;
+import com.revature.exceptions.InvalidRequestException;
+import com.revature.exceptions.ResourcePersistenceException;
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+import com.revature.repo.UserRepository;
+import com.revature.util.ConnectionFactory;
+import com.revature.util.Session;
+
+
+import static com.revature.BankingApp.app;
+
+public class UserService {
+
+ private UserRepository userRepo;
+
+ public UserService(UserRepository userRepo) {
+ this.userRepo = userRepo;
+ }
+
+ public void authenticate(String username, String password) {
+
+ if (username == null || username.trim().equals("") || password == null || password.trim().equals("")) {
+ throw new InvalidRequestException("Invalid credentials provided (null or empty strings)!");
+ }
+
+ AppUser authUser = userRepo.findUserByUsernameAndPassword(username, password);
+
+ if (authUser == null) {
+ throw new AuthenticationException();
+ }
+
+ app().setCurrentSession(new Session(authUser, ConnectionFactory.getInstance().getConnection()));
+
+ }
+
+ public void register(AppUser newUser) {
+
+ if (!isUserValid(newUser)){
+ throw new InvalidRequestException("Invalid new user provided!");
+ }
+
+ if (userRepo.findUserByUsername(newUser.getUsername()) != null) {
+ throw new ResourcePersistenceException("The provided username is already in use!");
+ }
+
+ newUser.setUserRole(UserRole.BASIC_USER);
+ userRepo.save(newUser);
+
+ }
+
+ public boolean isUserValid(AppUser user) {
+ if (user == null) return false;
+ if (user.getFirstName() == null || user.getFirstName().trim().equals("")) return false;
+ if (user.getLastName() == null || user.getLastName().trim().equals("")) return false;
+ if (user.getUsername() == null || user.getUsername().trim().equals("")) return false;
+ if (user.getPassword() == null || user.getPassword().trim().equals("")) return false;
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/AppState.java b/banking/src/main/java/com/revature/util/AppState.java
new file mode 100644
index 0000000..24261d5
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/AppState.java
@@ -0,0 +1,103 @@
+package com.revature.util;
+
+import com.revature.account.Account;
+import com.revature.models.AppUser;
+import com.revature.repo.AccountRepository;
+import com.revature.repo.UserRepository;
+import com.revature.screens.*;
+import com.revature.services.AccountService;
+import com.revature.services.UserService;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+public class AppState {
+
+ private BufferedReader console;
+ private ScreenRouter router;
+ private Session currentSession;
+ private boolean appRunning;
+ private Account account;
+ private AppUser appUser;
+ private int id;
+
+
+ public AppState() {
+
+ System.out.println("[LOG] - Initializing application...");
+
+ this.appRunning = true;
+ this.console = new BufferedReader(new InputStreamReader(System.in));
+
+ final UserRepository userRepo = new UserRepository();
+ final UserService userService = new UserService(userRepo);
+
+
+ final AccountRepository accountRepository=new AccountRepository();
+ final AccountService accountService=new AccountService(accountRepository);
+ AppUser appUser= new AppUser();
+ Account account=new Account();
+
+
+ router = new ScreenRouter();
+ router.addScreen(new HomeScreen())
+ .addScreen(new RegisterScreen(userService))
+ .addScreen(new LoginScreen(userService))
+ .addScreen(new Dashboard())
+ .addScreen(new AccountTypeScreen())
+ .addScreen(new TransactionScreen());
+
+ System.out.println("[LOG] - Application initialized");
+
+ }
+ public int getId(){ return id; }
+
+ public int setId(int id){ return this.id=id; }
+
+ public AppUser getAppUser(){ return appUser; }
+
+ public void setAppUser(AppUser appUser){
+ this.appUser=appUser;
+ }
+
+ public Account getAccount(){ return account; }
+
+ public void setAccount(Account account){
+ this.account=account;
+ }
+
+ public BufferedReader getConsole() {
+ return console;
+ }
+
+ public ScreenRouter getRouter() {
+ return router;
+ }
+
+ public boolean isAppRunning() {
+ return appRunning;
+ }
+
+ public void setAppRunning(boolean appRunning) {
+ this.appRunning = appRunning;
+ }
+
+ public Session getCurrentSession() {
+ return currentSession;
+ }
+
+ public void setCurrentSession(Session currentSession) {
+ this.currentSession = currentSession;
+ }
+
+ public void invalidateCurrentSession() {
+ this.currentSession = null;
+ }
+
+ public boolean isSessionValid() {
+ return (this.currentSession != null);
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/ConnectionFactory.java b/banking/src/main/java/com/revature/util/ConnectionFactory.java
new file mode 100644
index 0000000..e5911be
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/ConnectionFactory.java
@@ -0,0 +1,56 @@
+package com.revature.util;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionFactory {
+
+ private static ConnectionFactory connFactory = new ConnectionFactory();
+
+ private Properties props = new Properties();
+
+ static {
+ try {
+ Class.forName("org.postgresql.Driver");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private ConnectionFactory() {
+ try {
+ props.load(new FileReader("src/main/resources/application.properties"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static ConnectionFactory getInstance() {
+ return connFactory;
+ }
+
+ public Connection getConnection() {
+
+ Connection conn = null;
+
+ try {
+
+ conn = DriverManager.getConnection(
+ props.getProperty("url"),
+ props.getProperty("admin-usr"),
+ props.getProperty("admin-pw")
+ );
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return conn;
+
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/LinkedList.java b/banking/src/main/java/com/revature/util/LinkedList.java
new file mode 100644
index 0000000..04c7078
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/LinkedList.java
@@ -0,0 +1,116 @@
+package com.revature.util;
+
+import com.revature.models.AppUser;
+
+public class LinkedList {
+
+ private int size;
+ private Node head;
+ private Node tail;
+
+ public T findFirst(T data) {
+
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ if (currentNode.data.equals(data)) {
+ return currentNode.data;
+ }
+ }
+
+ return null;
+
+ }
+
+ public void insert(T data) {
+
+ if (data == null) {
+ return;
+ }
+
+ Node newNode = new Node<>(data);
+ if (head == null) {
+ tail = head = newNode;
+ } else {
+ tail.nextNode = newNode;
+ newNode.prevNode = tail;
+ tail = newNode;
+ }
+
+ size++;
+
+ }
+
+ public T pop() {
+
+ if (head == null) {
+ return null;
+ }
+
+ T popped = head.data;
+ head = head.nextNode;
+
+ if (head != null) {
+ head.prevNode = null;
+ }
+
+ size--;
+
+ return popped;
+
+ }
+
+ public T peek() {
+ return (head == null) ? null : head.data;
+ }
+
+ public boolean contains(T data) {
+
+ if (data == null) {
+ return false;
+ }
+
+ // Consensus dictates we should go with the for...because it makes people feel better. lol
+// Node currentNode = head;
+// while (currentNode != null) {
+// if (currentNode.data.equals(data)) {
+// return true;
+// }
+// currentNode = currentNode.nextNode;
+// }
+
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ if (currentNode.data.equals(data)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public void printList() {
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ System.out.println(currentNode.data);
+ }
+ }
+
+ private static class Node {
+ T data;
+ Node nextNode;
+ Node prevNode;
+
+ Node(T data) {
+ this.data = data;
+ }
+
+ Node(T data, Node nextNode, Node prevNode) {
+ this(data);
+ this.nextNode = nextNode;
+ this.prevNode = prevNode;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/Map.java b/banking/src/main/java/com/revature/util/Map.java
new file mode 100644
index 0000000..497ff68
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/Map.java
@@ -0,0 +1,166 @@
+package com.revature.util;
+
+import java.util.Arrays;
+
+public class Map {
+
+ private int size;
+ private final int DEFAULT_CAPACITY = 16;
+
+ @SuppressWarnings("unchecked")
+ private Entry[] entries = new Entry[DEFAULT_CAPACITY];
+
+ public boolean containsKey(K key) {
+ for (int i = 0; i < size; i++) {
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ return true;
+ }
+ } else if (entries[i].key.equals(key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public LinkedList keyList() {
+ LinkedList keyList = new LinkedList<>();
+ for (int i = 0; i < size; i++) {
+ keyList.insert(entries[i].key);
+ }
+ return keyList;
+ }
+
+ public V get(K key) {
+ for (int i = 0; i < size; i++) {
+
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ return entries[i].value;
+ }
+ } else if (entries[i].key.equals(key)) {
+ return entries[i].value;
+ }
+
+ }
+ return null;
+ }
+
+ public V getOrDefault(K key, V defaultValue) {
+
+ if (!containsKey(key)) {
+ return defaultValue;
+ }
+
+ return get(key);
+
+ }
+
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Adds a new entry to the map using the provided key and value. Returns the
+ * value previously associated with the key. If the key was not in the map prior,
+ * returns null.
+ *
+ * @param key
+ * @param value
+ * @return the previous value associated with the key, could return null
+ */
+ public V put(K key, V value) {
+
+ V previousValue = null;
+
+ boolean wasInserted = true;
+ for (int i = 0; i < size; i++) {
+
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ previousValue = entries[i].value;
+ entries[i].value = value;
+ wasInserted = false;
+ break;
+ }
+ } else if (entries[i].key.equals(key)) {
+ previousValue = entries[i].value;
+ entries[i].value = value;
+ wasInserted = false;
+ break;
+ }
+
+ }
+
+ if (wasInserted) {
+ ensureCapacity();
+ entries[size++] = new Entry<>(key, value);
+ }
+
+ return previousValue;
+
+ }
+
+ public void remove(K key) {
+
+ boolean wasRemoved = false;
+ for (int i = 0; i < size; i++) {
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ entries[i] = entries[size - 1];
+ size--;
+ wasRemoved = true;
+ }
+ } else if (entries[i].key.equals(key)) {
+ entries[i] = entries[size - 1];
+ size--;
+ wasRemoved = true;
+ }
+ }
+
+ if (wasRemoved) {
+ condenseArray();
+ }
+
+ }
+
+ public int size() {
+ return size;
+ }
+
+ // this method will be helpful after putting new entries into the map
+ private void ensureCapacity() {
+ if (size == entries.length) {
+ entries = Arrays.copyOf(entries, entries.length * 2);
+ }
+ }
+
+ // this method will be helpful after removing a key from the map
+ private void condenseArray() {
+ if (size * 2 < entries.length) {
+ entries = Arrays.copyOf(entries, entries.length / 2);
+ }
+ }
+
+ private static class Entry {
+
+ private final K key;
+ private V value;
+
+ public Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry{" +
+ "key=" + key +
+ ", value=" + value +
+ '}';
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/ScreenRouter.java b/banking/src/main/java/com/revature/util/ScreenRouter.java
new file mode 100644
index 0000000..ee14283
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/ScreenRouter.java
@@ -0,0 +1,36 @@
+package com.revature.util;
+
+import com.revature.screens.Screen;
+
+import java.util.LinkedList;
+
+//facilitates the routing from one screen to another instead of instanciating a new class every time
+//complications with creating new objects for each screen; we only need one instance of each screen
+public class ScreenRouter {
+ private Set screens=new Set<>();
+
+ // getter method for linked list
+ public Set getScreen(){
+ return screens;
+ }
+
+
+ //adding a type of screen for the user
+ public ScreenRouter addScreen(Screen screen){
+ System.out.println("[LOG] - Loading "+screen.getName()+" into router");
+ screens.add(screen);
+ return this;
+ }
+
+ //searching through an array of screens to navigate to the correct one once called
+ public void navigate(String route){
+
+ for(Screen screen : screens.toArray(Screen.class)){
+ if(screen.getRoute().equals(route)){
+ screen.render();
+ }
+ }
+
+ }
+
+}
diff --git a/banking/src/main/java/com/revature/util/Session.java b/banking/src/main/java/com/revature/util/Session.java
new file mode 100644
index 0000000..8d2d71f
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/Session.java
@@ -0,0 +1,51 @@
+package com.revature.util;
+
+import com.revature.account.Account;
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+
+import java.sql.Connection;
+
+public class Session {
+
+ private AppUser sessionUser;
+ private Connection connection;
+ private Account account;
+
+ public Session(AppUser sessionUser, Connection connection) {
+
+ if (sessionUser == null || connection == null) {
+ throw new ExceptionInInitializerError("Cannot establish user session, null values provided!");
+ }
+
+ this.sessionUser = sessionUser;
+ this.connection = connection;
+
+
+ }
+
+ public AppUser getSessionUser() {
+ return sessionUser;
+ }
+
+ public void setSessionUser(AppUser sessionUser) {
+ this.sessionUser = sessionUser;
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public void setConnection(Connection connection) {
+ this.connection = connection;
+ }
+
+ public Account getAccount(){ return account; }
+
+ public void setAccount(Account account){this.account=account;}
+
+ public boolean isAdmin() {
+ return (sessionUser.getUserRole().equals(UserRole.ADMIN));
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/java/com/revature/util/Set.java b/banking/src/main/java/com/revature/util/Set.java
new file mode 100644
index 0000000..93f1b95
--- /dev/null
+++ b/banking/src/main/java/com/revature/util/Set.java
@@ -0,0 +1,46 @@
+package com.revature.util;
+
+import java.lang.reflect.Array;
+
+public class Set {
+
+ private Map map;
+
+ public Set() {
+ this.map = new Map<>();
+ }
+
+ public boolean add(T data) {
+ return this.map.put(data, data.hashCode()) == null;
+ }
+
+ public boolean contains(T data) {
+ return this.map.containsKey(data);
+ }
+
+ public boolean isEmpty() {
+ return this.map.isEmpty();
+ }
+
+ // TODO: probably should return something other than true all the time. maybe?
+ public boolean remove(T data) {
+ this.map.remove(data);
+ return true;
+ }
+
+ public int size() {
+ return this.map.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ public T[] toArray(Class clazz) {
+ LinkedList keys = this.map.keyList();
+ T[] keyArr = (T[]) Array.newInstance(clazz, size());
+ for (int i = 0; i < size(); i++) {
+ T t = keys.pop();
+ keyArr[i] = t;
+ }
+ return keyArr;
+ }
+
+}
\ No newline at end of file
diff --git a/banking/src/main/resources/table-creation.sql b/banking/src/main/resources/table-creation.sql
new file mode 100644
index 0000000..53381e1
--- /dev/null
+++ b/banking/src/main/resources/table-creation.sql
@@ -0,0 +1,24 @@
+create table user_roles (
+ role_id serial,
+ role_name varchar(25) unique not null,
+
+ constraint user_roles_pk
+ primary key (role_id)
+);
+
+create table app_users (
+ user_id serial,
+ username varchar unique not null,
+ password varchar not null,
+ first_name varchar not null,
+ last_name varchar not null,
+ role_id int not null,
+
+ constraint app_users_pk
+ primary key (user_id),
+
+ constraint app_user_role_fk
+ foreign key (role_id)
+ references user_roles
+
+);
\ No newline at end of file
diff --git a/banking/src/test/java/ConnectionFactoryTest.java b/banking/src/test/java/ConnectionFactoryTest.java
new file mode 100644
index 0000000..8372f07
--- /dev/null
+++ b/banking/src/test/java/ConnectionFactoryTest.java
@@ -0,0 +1,19 @@
+package com.revature.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class ConnectionFactoryTest {
+
+ public static void main(String[] args) {
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+ if (conn == null) {
+ System.err.println("You didn't make a connection, noob.");
+ } else {
+ System.out.println("Ok so maybe you kinda know what you're doing.");
+ }
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/banking/src/test/java/MapTest.java b/banking/src/test/java/MapTest.java
new file mode 100644
index 0000000..eb0afcc
--- /dev/null
+++ b/banking/src/test/java/MapTest.java
@@ -0,0 +1,37 @@
+package com.revature.util;
+
+public class MapTest {
+
+ public static void main(String[] args) {
+ Map mapTest = new Map<>();
+ mapTest.put("test1", 1);
+ System.out.println("size = " + mapTest.size());
+ mapTest.remove("test1");
+ System.out.println("size = " + mapTest.size());
+
+// mapTest.put("test2", 2);
+// mapTest.put("test3", 3);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of test1 = " + mapTest.get("test1"));
+// System.out.println("value of test2 = " + mapTest.get("test2"));
+// System.out.println("value of test3 = " + mapTest.get("test3"));
+//
+// mapTest.put("test1", -1);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of test1 = " + mapTest.get("test1"));
+//
+// mapTest.put(null, 0);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of null = " + mapTest.get(null));
+//
+// System.out.println(mapTest.containsKey("test2"));
+// System.out.println(mapTest.containsKey(null));
+// System.out.println(mapTest.containsKey("fakeKey"));
+//
+// mapTest.put("nullVal", null);
+// System.out.println(mapTest.getOrDefault("nullVal", -5));
+// System.out.println(mapTest.containsKey(null));
+
+ }
+
+}
\ No newline at end of file
diff --git a/day-3/.idea/.gitignore b/day-3/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/day-3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/day-3/.idea/misc.xml b/day-3/.idea/misc.xml
new file mode 100644
index 0000000..0548357
--- /dev/null
+++ b/day-3/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-3/.idea/modules.xml b/day-3/.idea/modules.xml
new file mode 100644
index 0000000..b7a1541
--- /dev/null
+++ b/day-3/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-3/.idea/vcs.xml b/day-3/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/day-3/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-3/day-3.iml b/day-3/day-3.iml
new file mode 100644
index 0000000..c90834f
--- /dev/null
+++ b/day-3/day-3.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-3/out/production/day-3/com/revature/Driver.class b/day-3/out/production/day-3/com/revature/Driver.class
new file mode 100644
index 0000000..6619085
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/Driver.class differ
diff --git a/day-3/out/production/day-3/com/revature/abstractions/Animal.class b/day-3/out/production/day-3/com/revature/abstractions/Animal.class
new file mode 100644
index 0000000..770da7d
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/abstractions/Animal.class differ
diff --git a/day-3/out/production/day-3/com/revature/abstractions/Cat.class b/day-3/out/production/day-3/com/revature/abstractions/Cat.class
new file mode 100644
index 0000000..6315a5c
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/abstractions/Cat.class differ
diff --git a/day-3/out/production/day-3/com/revature/abstractions/abstractDriver.class b/day-3/out/production/day-3/com/revature/abstractions/abstractDriver.class
new file mode 100644
index 0000000..396a74f
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/abstractions/abstractDriver.class differ
diff --git a/day-3/out/production/day-3/com/revature/arrays/ArrayDemo.class b/day-3/out/production/day-3/com/revature/arrays/ArrayDemo.class
new file mode 100644
index 0000000..9272988
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/arrays/ArrayDemo.class differ
diff --git a/day-3/out/production/day-3/com/revature/overloading/MethodOverloader.class b/day-3/out/production/day-3/com/revature/overloading/MethodOverloader.class
new file mode 100644
index 0000000..c1f9de7
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/overloading/MethodOverloader.class differ
diff --git a/day-3/out/production/day-3/com/revature/strings/StringDriver.class b/day-3/out/production/day-3/com/revature/strings/StringDriver.class
new file mode 100644
index 0000000..5ca4368
Binary files /dev/null and b/day-3/out/production/day-3/com/revature/strings/StringDriver.class differ
diff --git a/day-3/src/com/revature/Driver.java b/day-3/src/com/revature/Driver.java
new file mode 100644
index 0000000..1c8943b
--- /dev/null
+++ b/day-3/src/com/revature/Driver.java
@@ -0,0 +1,19 @@
+package com.revature;
+
+import com.revature.arrays.ArrayDemo;
+import com.revature.overloading.MethodOverloader;
+
+public class Driver {
+
+ public static void main(String[] args){
+
+ ArrayDemo arraydemo=new ArrayDemo();
+ arraydemo.learningArrays();
+
+ MethodOverloader methodOverloader=new MethodOverloader();
+
+ // methodOverloader.test(new Integer(1));
+ methodOverloader.test(1,2,3,4);
+
+ }
+}
diff --git a/day-3/src/com/revature/abstractions/Animal.java b/day-3/src/com/revature/abstractions/Animal.java
new file mode 100644
index 0000000..cd465b1
--- /dev/null
+++ b/day-3/src/com/revature/abstractions/Animal.java
@@ -0,0 +1,34 @@
+package com.revature.abstractions;
+/*
+Abstract classes
+ >cannot be directly instantiated, must have
+ a concrete implementation by means of one or more subclasses
+ +all abstract methods in the class MUST be implemented by concrete subclasses
+
+ >Still have constructors ,becuase subclasses will leverage these for their own instantiation
+
+ >can have zero or more abstact methods contained within its declaration.
+ +abstract methods are simply methods that do not have any implementaton, also called "method stubs
+
+ */
+abstract class Animal {
+ public int numberofLives=1;
+ public String value;
+ public String thing;
+
+ public Animal(){
+ System.out.println("Animal constructor called!");
+
+ }
+ //concreate method(method with an implementation)
+ public void eat(){
+ System.out.println("the animal eats");
+ }
+ //abstract method
+ public abstract void makesound();
+
+ public static void doStuff(){
+ System.out.println("this cat is doing stuff ");
+ }
+
+}
diff --git a/day-3/src/com/revature/abstractions/Cat.java b/day-3/src/com/revature/abstractions/Cat.java
new file mode 100644
index 0000000..f4d6f01
--- /dev/null
+++ b/day-3/src/com/revature/abstractions/Cat.java
@@ -0,0 +1,52 @@
+package com.revature.abstractions;
+
+public class Cat extends Animal{
+
+ //shadowing
+ public int numberofLives=1;
+ private String breed;
+ private boolean hasfur;
+
+ public Cat(int numberofLives) {
+ System.out.println("peramertirized constructor");
+ this.numberofLives = numberofLives;
+ }
+
+ public Cat(){
+ System.out.println("noargs constructor");
+ this.numberofLives=9;
+ this.breed="shorthair";
+ this.hasfur=true;
+ this.value="cat value";
+ this.thing="cat thing";
+
+ }
+
+
+
+ @Override //<--annotation
+ public void makesound() {
+
+ }
+ //cannot include @override here without an error, since this method is not declared in Animal
+ public void makecookies(){
+ System.out.println("awwww cute, cat makes cookies");
+ }
+
+
+
+
+ /* @Override
+ public static void doStuff(){
+ System.out.println("this cat is doing stuff");
+ }
+*/
+
+ public int getNumberofLives() {
+ return numberofLives;
+ }
+
+ public void setNumberofLives(int numberofLives) {
+ this.numberofLives = numberofLives;
+ }
+}
diff --git a/day-3/src/com/revature/abstractions/abstractDriver.java b/day-3/src/com/revature/abstractions/abstractDriver.java
new file mode 100644
index 0000000..f206669
--- /dev/null
+++ b/day-3/src/com/revature/abstractions/abstractDriver.java
@@ -0,0 +1,26 @@
+package com.revature.abstractions;
+
+public class abstractDriver{
+ public static void main(String[] args){
+ //cannot directly instantiate abstract classes!
+
+ Cat myCat=new Cat();
+
+ Animal someAnimal=new Cat();//covariance
+ /*
+ covariance is when you hace a reference
+ of a super type that points to an object
+ of a subtype. This regerence wil have access to only
+ the states and behaviors
+ of the declared reference type . although , if
+ any methods of the parent are overridden by
+ the subtype, those methods will behave as they do for the
+ subtype
+
+ */
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/day-3/src/com/revature/arrays/ArrayDemo.java b/day-3/src/com/revature/arrays/ArrayDemo.java
new file mode 100644
index 0000000..2258921
--- /dev/null
+++ b/day-3/src/com/revature/arrays/ArrayDemo.java
@@ -0,0 +1,107 @@
+package com.revature.arrays;
+
+import com.revature.Driver;
+
+import java.util.Arrays;
+
+public class ArrayDemo {
+
+ String someValue;
+
+ public ArrayDemo(){
+ super(); //remember:not actually required
+
+
+ }
+
+ public ArrayDemo(String someValue){
+ this.someValue=someValue;
+
+ }
+
+ public void learningArrays(){
+ boolean dontRun=false;
+
+ if(dontRun){
+ //void methods cant return values
+ //but you can still use the return keyword
+
+ return;//ends the method early if the condition is true
+ }
+
+ // Arrays declarations
+ //int arr=new int[5];
+ //int [] arr=new int[5];
+ //int arr[]=new int[5];
+ //int arr={2,3,5,7,11}; <--array literal notation
+
+ /*
+ Arrays are of fixed size in Java, meaning that once
+ instantiated(created) their size cannot be changed.
+
+
+ */
+ Object[] arr={2,3,0,5,"works",new Driver()};
+ Object o1=arr[3];
+ // Object o2=(String)arr[3];
+ String o3=arr[4].toString();
+
+ System.out.println(o3);
+
+ System.out.println("String representation"+ arr);
+ //not super usful, doesnt show members of the array
+
+ System.out.println(Arrays.toString(arr));
+ //works differently, actually shows members
+
+ int[] intArray={432,72,24,42,-5,0};
+
+ System.out.println(Arrays.toString(intArray));
+ Arrays.sort(intArray);
+ System.out.println(Arrays.toString(intArray));
+
+ /*
+ Accessing and manipulating array values
+ >java arrays start an index position at 0
+ >Use "bracket notation" to access array values by their index position
+
+
+ */
+
+ System.out.println(intArray[0]);
+ intArray[0]=7860;
+ System.out.println(intArray[0]);
+
+ //throws an ArrayIndexOutOfBoundsException for any value that is not in the array
+ // System.out.println(intArray[-1]);
+
+ //methods that have the same name, but differing
+ //return types
+
+ /*
+ compile time (static polymorphism
+ +compile-time, because the method that
+ +youll use can be determined a complie time
+ +based on the values you pass into the method call
+
+ */
+
+ if(arr[4] instanceof String){
+ System.out.println( arr[4]);
+ }
+ else {
+ System.out.println("this arr is not a string");
+ }
+
+
+
+ }
+ //traditional for loop to print each member of the array
+ public void printvalues(int[] intArray){
+ for(int i=0; iMemory managment of Strings (String pool)
+ >String API(Application programing Interface
+ >StringBuilder/StringBuffer classes
+ */
+
+ public static void main(String[] args){
+ String s1="hello";
+ String s2="hello";
+ String s3=new String("hello");
+ String s4=null;
+
+ /*
+ String pool
+ >A special area inside of heap memory that
+ java leverages to store String Objects with
+ unique values. (implements the flywheel design pattern)
+
+ >Not all Strings are stored in the String pool
+ +if you explicitly use new to instatie te string
+ +Strings that are returned from any String API method are not in the pool
+ >If you use literal notation with the same value as
+ an existing string,, a single string object will be stored in the pool.
+
+
+
+
+ */
+
+ System.out.println(s1==s2);//true, since we created two Strings using
+ //literal notation
+
+ System.out.println(s1==s3);//false, since we used the new keyword
+
+ System.out.println(s1.equals(s3));//true; because we are cheacking value
+
+ /*
+ Stirng interning is the act of moving a String -which
+ exists outside of the string pool -and interning or moving
+ in into the string pool
+
+ */
+ String s5=s3.intern();
+ System.out.println(s1==s3);
+ //s3 techically didnt get interned, the method retured an interned string
+ System.out.println(s2==s3);
+ //also false
+ System.out.println(s1==s5);
+ //true, s5 regerence the same object as s1(and s2)
+
+ /*
+ The imutability of Strings
+ -Strings are imutable (their value cant be changed
+ +implicitly thred-safe as a result
+
+ */
+
+ String s6="hello ";
+ s6.concat(",world");
+ System.out.println(s6);
+ //the result of .concat returned a new String and we ignored it
+ s6=s6.concat(",world");
+ System.out.println(s6);
+ String s7="hello ,world";
+ System.out.println(s6==s7);
+
+ s6=s6.intern();
+ System.out.println(s6==s7);
+
+
+ /*
+ String Builder and String buffer
+ String builder
+ -it does not extend the string class
+ -mutable
+ -cannot be instantiated using string literals
+ -not thread safe
+
+ String Builder
+ -same thing but is thread safe
+
+
+ */
+ StringBuilder sb1=new StringBuilder("hello");
+ StringBuffer sb2=new StringBuffer("hello");
+
+ System.out.println(sb1.equals(sb2));//false
+ //because for some reason string builder do not override
+ //the .equals method from obect
+
+ }
+}
diff --git a/day-4/.gradle/6.7/executionHistory/executionHistory.lock b/day-4/.gradle/6.7/executionHistory/executionHistory.lock
new file mode 100644
index 0000000..dc4a46e
Binary files /dev/null and b/day-4/.gradle/6.7/executionHistory/executionHistory.lock differ
diff --git a/day-4/.gradle/6.7/fileChanges/last-build.bin b/day-4/.gradle/6.7/fileChanges/last-build.bin
new file mode 100644
index 0000000..f76dd23
Binary files /dev/null and b/day-4/.gradle/6.7/fileChanges/last-build.bin differ
diff --git a/day-4/.gradle/6.7/fileHashes/fileHashes.lock b/day-4/.gradle/6.7/fileHashes/fileHashes.lock
new file mode 100644
index 0000000..5946d5d
Binary files /dev/null and b/day-4/.gradle/6.7/fileHashes/fileHashes.lock differ
diff --git a/day-4/.gradle/6.7/gc.properties b/day-4/.gradle/6.7/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/day-4/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/day-4/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000..a46465e
Binary files /dev/null and b/day-4/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/day-4/.gradle/buildOutputCleanup/cache.properties b/day-4/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000..6360ce8
--- /dev/null
+++ b/day-4/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Fri Jan 22 14:57:35 CST 2021
+gradle.version=6.7
diff --git a/day-4/.gradle/checksums/checksums.lock b/day-4/.gradle/checksums/checksums.lock
new file mode 100644
index 0000000..05d9b57
Binary files /dev/null and b/day-4/.gradle/checksums/checksums.lock differ
diff --git a/day-4/.gradle/configuration-cache/gc.properties b/day-4/.gradle/configuration-cache/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/day-4/.gradle/vcs-1/gc.properties b/day-4/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/day-4/.idea/.gitignore b/day-4/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/day-4/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/day-4/.idea/compiler.xml b/day-4/.idea/compiler.xml
new file mode 100644
index 0000000..0f72b8c
--- /dev/null
+++ b/day-4/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-4/.idea/jarRepositories.xml b/day-4/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/day-4/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-4/.idea/misc.xml b/day-4/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/day-4/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-4/.idea/vcs.xml b/day-4/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/day-4/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-4/day-4.iml b/day-4/day-4.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/day-4/day-4.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/day-4/pom.xml b/day-4/pom.xml
new file mode 100644
index 0000000..c295ea4
--- /dev/null
+++ b/day-4/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ com.revature
+ day-4
+ 1.0-SNAPSHOT
+
+
+ 1.8
+
+ 1.8
+
+
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/Driver.java b/day-4/src/main/java/com/revature/Driver.java
new file mode 100644
index 0000000..3b87345
--- /dev/null
+++ b/day-4/src/main/java/com/revature/Driver.java
@@ -0,0 +1,8 @@
+package com.revature;
+
+public class Driver {
+ public static void main(String[] args){
+ System.out.println("Hello world!");
+
+ }
+}
diff --git a/day-4/src/main/java/com/revature/classloading/Bird.java b/day-4/src/main/java/com/revature/classloading/Bird.java
new file mode 100644
index 0000000..3fdf4c7
--- /dev/null
+++ b/day-4/src/main/java/com/revature/classloading/Bird.java
@@ -0,0 +1,21 @@
+package com.revature.classloading;
+
+public class Bird {
+
+ // Non-static initialization blocks
+ // RUN BEFORE CONSTRUCTOR LOGIC (IN THE ORDER THEY ARE DECLARED)
+ {
+ System.out.println("b1");
+ }
+
+ Bird() {
+ System.out.println("b2");
+ }
+
+ // Static initialization blocks
+ // RUN WHEN THE CLASS DECLARATION IS LOADED INTO JVM MEMORY (BEFORE ANY OBJECT INSTANTIATION)
+ static {
+ System.out.println("b3");
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/classloading/Hawk.java b/day-4/src/main/java/com/revature/classloading/Hawk.java
new file mode 100644
index 0000000..79729d6
--- /dev/null
+++ b/day-4/src/main/java/com/revature/classloading/Hawk.java
@@ -0,0 +1,12 @@
+package com.revature.classloading;
+
+
+public class Hawk extends Raptor {
+
+ public static void main(String[] args) {
+ System.out.println("init");
+ new Hawk();
+ System.out.println("hawk");
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/classloading/Parrot.java b/day-4/src/main/java/com/revature/classloading/Parrot.java
new file mode 100644
index 0000000..d0c6b3b
--- /dev/null
+++ b/day-4/src/main/java/com/revature/classloading/Parrot.java
@@ -0,0 +1,8 @@
+package com.revature.classloading;
+
+public class Parrot {
+
+ static{
+ System.out.println("p1");
+ }
+}
diff --git a/day-4/src/main/java/com/revature/classloading/Raptor.java b/day-4/src/main/java/com/revature/classloading/Raptor.java
new file mode 100644
index 0000000..4bc1a94
--- /dev/null
+++ b/day-4/src/main/java/com/revature/classloading/Raptor.java
@@ -0,0 +1,27 @@
+import com.revature.classloading.Bird;
+
+public class Raptor extends Bird {
+
+ static {
+ System.out.println("r1");
+ }
+
+ Raptor() {
+
+ System.out.println("r2");
+ }
+
+ // You would not really ever have more than one non-static init block
+ {
+ System.out.println("r5");
+ }
+
+ {
+ System.out.println("r3");
+ }
+
+ static {
+ System.out.println("r4");
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/interfaces/InterfaceA.java b/day-4/src/main/java/com/revature/interfaces/InterfaceA.java
new file mode 100644
index 0000000..059d1ae
--- /dev/null
+++ b/day-4/src/main/java/com/revature/interfaces/InterfaceA.java
@@ -0,0 +1,18 @@
+package com.revature.interfaces;
+
+public interface InterfaceA {
+ int value=10;//implicitly public static final
+ void method();//implicitly abstract
+
+ //add in java 8 for backwards compatability
+
+ default void method2(){
+ System.out.println("interface method with a default implementation!");
+ }
+
+ //Java as pretty much always allowed for interface to have static methods
+ static void method3(){
+ System.out.println("I cannot be overridden, but I can be shadowed/redeclared!");
+
+ }
+}
diff --git a/day-4/src/main/java/com/revature/io/ReadConsoleDriver.java b/day-4/src/main/java/com/revature/io/ReadConsoleDriver.java
new file mode 100644
index 0000000..3768015
--- /dev/null
+++ b/day-4/src/main/java/com/revature/io/ReadConsoleDriver.java
@@ -0,0 +1,78 @@
+package com.revature.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class ReadConsoleDriver {
+
+ // System.in represents the input stream from the console
+ // Scanner is particularly useful for parsing input streams
+// static Scanner consoleReader = new Scanner(System.in);
+
+ public static void main(String[] args) {
+
+// // Reading input from the console using Scanner class
+// System.out.print("Please enter your username: ");
+// String username = consoleReader.next();
+//
+// System.out.print("Please enter your password: ");
+// String password = consoleReader.next();
+//
+// System.out.printf("The credentials you provided were: %s and %s\n", username, password);
+//
+// int age = getAge();
+// System.out.printf("Your age is: %d", age);
+
+ //-----------------------------------------------------
+
+ // Reading input from the console using BufferedReader
+
+ // Verbose declaration
+// InputStreamReader inputStreamReader = new InputStreamReader(System.in);
+// BufferedReader verboseReader = new BufferedReader(inputStreamReader);
+
+ // Concise declaration
+ BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
+
+ try {
+ System.out.print("Please enter your first name: ");
+ String firstName = consoleReader.readLine();
+ System.out.printf("Your name is %s", firstName);
+
+ System.out.print("\nProvide your age: ");
+ String stringAge = consoleReader.readLine();
+ int age = Integer.parseInt(stringAge);
+ System.out.printf("You will be 40 in %d years", (40 - age));
+
+ } catch (IOException | NumberFormatException e) {
+ System.err.println("Oh no! You didn't give me a number!");
+ e.printStackTrace(); // used for debugging (usually will be logged to an external file)
+ }
+
+
+ }
+
+ public static int getAge() {
+
+// int age; // uninitialized, has no default value (not even 0)
+
+// int age = 0;
+// try {
+// System.out.print("Please enter your age: ");
+// age = consoleReader.nextInt(); // can throw an InputMismatchException if given bad data
+// } catch (InputMismatchException ime) {
+// System.err.println("\nCaught InputMismatchException");
+// ime.printStackTrace();
+// } catch (Exception e) {
+// System.err.println("\nThat's not a number, dummy.");
+//// age = getAge(); // recursive call results in a StackOverflowError
+// }
+//
+// return age;
+
+ return 0;
+
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/io/ReadFileDriver.java b/day-4/src/main/java/com/revature/io/ReadFileDriver.java
new file mode 100644
index 0000000..c1b2d2b
--- /dev/null
+++ b/day-4/src/main/java/com/revature/io/ReadFileDriver.java
@@ -0,0 +1,43 @@
+package com.revature.io;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class ReadFileDriver {
+
+ public static void main(String[] args) {
+
+ File happyText = new File("src/main/resources/happy-text.txt");
+
+ if (!happyText.exists()) {
+ System.err.println("Oh no! That file doesn't exist!");
+ return;
+ }
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(happyText));
+ String currentLine = reader.readLine();
+
+ while (currentLine != null) {
+ System.out.println(currentLine);
+ currentLine = reader.readLine();
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ // this is gross, but necessary in order to avoid memory leaks
+ // but there is a syntactically cleaner way! (see WriteFileDriver.java)
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/io/WriteFileDriver.java b/day-4/src/main/java/com/revature/io/WriteFileDriver.java
new file mode 100644
index 0000000..8ecb116
--- /dev/null
+++ b/day-4/src/main/java/com/revature/io/WriteFileDriver.java
@@ -0,0 +1,31 @@
+package com.revature.io;
+
+import com.revature.models.Person;
+import com.revature.models.Role;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class WriteFileDriver {
+
+ public static void main(String[] args) {
+
+ File fileToWrite = new File("src/main/resources/write-to-me.txt");
+
+ /*
+ Try-with-resources
+ - Introduced in Java 7
+ - automatically closes objects declared as resources (more than one is allowed)
+ - only allows for the declaration of resources that implement the AutoCloseable interface
+ */
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileToWrite, true))) { // <-- that boolean means to append
+ Person me = new Person(1, "wsingleton", "password", Role.TRAINER);
+ writer.write("\n" + me.toString());
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/models/Person.java b/day-4/src/main/java/com/revature/models/Person.java
new file mode 100644
index 0000000..176c640
--- /dev/null
+++ b/day-4/src/main/java/com/revature/models/Person.java
@@ -0,0 +1,122 @@
+package com.revature.models;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/*
+ POJO Design Pattern
+ - Acronym: "Plain Ol' Java Objects"
+ - Design pattern that encapsulates the states and behaviors of a domain object
+ - Synonyms: models, entities, beans
+ - Characteristics:
+ + have private fields/attributes/states
+ + has one or more constructors for instantiating the class
+ + exposes getters/setters for each private field
+ + overrides the Object class's .equals(), .hashcode(), and .toString()
+ */
+public class Person implements Serializable {
+
+ private int id;
+ private String username;
+ private String password;
+ private Role role;
+
+ public Person() {
+ super();
+ }
+
+ public Person(String username, String password, Role role) {
+ this.username = username;
+ this.password = password;
+ this.role = role;
+ }
+
+ public Person(int id, String username, String password, Role role) {
+ this(username, password, role);
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Role getRole() {
+ return role;
+ }
+
+ public void setRole(Role role) {
+ this.role = role;
+ }
+
+ // Pre-Java v7 syntax for Object.equals()
+// @Override
+// public boolean equals(Object o) {
+// if (this == o) return true;
+// if (o == null || getClass() != o.getClass()) return false;
+//
+// Person person = (Person) o;
+//
+// if (id != person.id) return false;
+// if (username != null ? !username.equals(person.username) : person.username != null) return false;
+// if (password != null ? !password.equals(person.password) : person.password != null) return false;
+// return role == person.role;
+// }
+
+
+ // Java v7+ syntax for Object.equals()
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Person person = (Person) o;
+ return id == person.id &&
+ Objects.equals(username, person.username) &&
+ Objects.equals(password, person.password) &&
+ role == person.role;
+ }
+
+// @Override
+// public int hashCode() {
+// int result = id;
+// result = 31 * result + (username != null ? username.hashCode() : 0);
+// result = 31 * result + (password != null ? password.hashCode() : 0);
+// result = 31 * result + (role != null ? role.hashCode() : 0);
+// return result;
+// }
+
+ // Java v7+ syntax for Object.hashcode()
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, username, password, role);
+ }
+
+ @Override
+ public String toString() {
+ return "Person{" +
+ "id=" + id +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", role=" + role +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/day-4/src/main/java/com/revature/models/Role.java b/day-4/src/main/java/com/revature/models/Role.java
new file mode 100644
index 0000000..d35b609
--- /dev/null
+++ b/day-4/src/main/java/com/revature/models/Role.java
@@ -0,0 +1,17 @@
+package com.revature.models;
+/*
+Java Enums
+ -enumerated types
+ -used to define a collection of constat values
+ -constructors of enums are always (and implicitly private)
+ -the can have static methods
+ */
+
+ //enum==Enumerated type
+ public enum Role{
+ ADMIN, DEV, TRAINER, QC_ANALYST, BLDG_MNGR,SITE_MNGR
+
+
+
+ }
+
diff --git a/day-5/.idea/.gitignore b/day-5/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/day-5/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/day-5/.idea/compiler.xml b/day-5/.idea/compiler.xml
new file mode 100644
index 0000000..3c7f42f
--- /dev/null
+++ b/day-5/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-5/.idea/jarRepositories.xml b/day-5/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/day-5/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-5/.idea/misc.xml b/day-5/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/day-5/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-5/.idea/vcs.xml b/day-5/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/day-5/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/day-5/day-5.iml b/day-5/day-5.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/day-5/day-5.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/day-5/pom.xml b/day-5/pom.xml
new file mode 100644
index 0000000..4ffe000
--- /dev/null
+++ b/day-5/pom.xml
@@ -0,0 +1,23 @@
+
+
+ 4.0.0
+
+ org.example
+ day-5
+ 1.0-SNAPSHOT
+
+
+ com.thoughtworks.xstream
+ xstream
+ 1.3.1
+
+
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/day-5/src/main/java/com/revature/nested/Driver.java b/day-5/src/main/java/com/revature/nested/Driver.java
new file mode 100644
index 0000000..6f89304
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/Driver.java
@@ -0,0 +1,58 @@
+package com.revature.nested;
+//import com.revature.nested.Outerclass;
+
+import static com.revature.nested.Outerclass.StaticInnerclass;
+public class Driver {
+
+ public static void main(String[]args){
+
+// //we can declare the type by utilizing the 'dot' operator for the type outerclass.innerClass inner=new outerClass.innerClass(")
+// Outerclass.Innerclass.inner2=new Outerclass().new Innerclass(innerState"");
+//
+// //Her we can
+// Outerclass outer=new Outerclass();
+//
+// Outerclass.Innerclass inner= outer.new Innerclass(innerState"");
+
+ // Outerclass.StaticInnerclass innerStatic= new Outerclass.StaticInnerclass;
+// Object innerState;
+// StaticInnerclass innerStatic=new StaticInnerclass(innerState"this is the new inner state");
+// System.out.println(innerStatic.getInnerState());
+
+//
+// class NestedConcrete extends SimpleAbstractClass{
+// @Override
+// public int sum(int a, int b) {
+// return a+b;
+// }
+// }
+// NestedConcrete nested=new NestedConcrete();
+// System.out.println(nested.sum(34,43));
+//
+// class OperableImpl implements SimpleInterface{
+//
+// @Override
+// public int operate(double a, double b) {
+// return 0;
+// }
+// }
+// SimpleInterface oper=new OperableImpl();
+// System.out.println(oper.operate(34.4,342.3));
+// SimpleInterface lan=(double a,double b)->{
+// return a/b;
+// };
+// System.out.println((lan.operate(34.23,234.5)));
+
+ Printable print=(s)-> System.out.println(s);
+ print.print("this was done with a lambda");
+
+ //method reference
+ Printable print2= System.out::println;
+ print2.print("this was done with a method reference");
+
+
+
+ }
+
+}
+
diff --git a/day-5/src/main/java/com/revature/nested/LongTester.java b/day-5/src/main/java/com/revature/nested/LongTester.java
new file mode 100644
index 0000000..0b5523e
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/LongTester.java
@@ -0,0 +1,48 @@
+package com.revature.nested;
+
+import java.util.function.LongPredicate;
+
+public class LongTester {
+ Long value;
+
+ public LongTester(Long value) {
+ this.value = value;
+ }
+
+ public Long getValue() {
+ return value;
+ }
+//lambda provides the implementation for the method 'test' on the instance of LongPredicate
+ public final LongPredicate greaterThan=l ->value>l;
+
+ public final LongPredicate lessThan=l ->valuel==value;
+
+ public final LongPredicate LessThanOrEven=l->(lMath.pow(l,2)>120_000);
+ System.out.println("did the custom test work?"+ b);
+
+
+ }
+}
diff --git a/day-5/src/main/java/com/revature/nested/Outerclass.java b/day-5/src/main/java/com/revature/nested/Outerclass.java
new file mode 100644
index 0000000..6ada4c8
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/Outerclass.java
@@ -0,0 +1,37 @@
+package com.revature.nested;
+
+/*
+we can nest a class inside another class to determine
+a shape of a custome state
+access modifiers are sill applicable to inner types
+
+ */
+public class Outerclass {
+ //sope? instance scoped
+ private int someNum;
+ public class Innerclass {
+ private String innerState;
+
+ public String getInnerState() {
+ return innerState;
+ }
+
+ public void setInnerState(String innerState) {
+ this.innerState = innerState;
+
+ }
+
+ //The inner class has access to its parents private members
+
+ public void InnerClass(String innerState) {
+ this.innerState = innerState + "and the outer stateis: " + someNum;
+ }
+ }
+ public static class StaticInnerclass{
+ private String innerState;
+
+ public void getInnerState() {
+ }
+ }
+
+}
diff --git a/day-5/src/main/java/com/revature/nested/Printable.java b/day-5/src/main/java/com/revature/nested/Printable.java
new file mode 100644
index 0000000..5b1940b
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/Printable.java
@@ -0,0 +1,6 @@
+package com.revature.nested;
+
+@FunctionalInterface
+public interface Printable {
+ void print(String s);
+}
diff --git a/day-5/src/main/java/com/revature/nested/SimpleAbstractClass.java b/day-5/src/main/java/com/revature/nested/SimpleAbstractClass.java
new file mode 100644
index 0000000..547d682
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/SimpleAbstractClass.java
@@ -0,0 +1,6 @@
+package com.revature.nested;
+
+public abstract class SimpleAbstractClass {
+
+ public abstract int sum(int a, int b);
+}
diff --git a/day-5/src/main/java/com/revature/nested/SimpleInterface.java b/day-5/src/main/java/com/revature/nested/SimpleInterface.java
new file mode 100644
index 0000000..0b43313
--- /dev/null
+++ b/day-5/src/main/java/com/revature/nested/SimpleInterface.java
@@ -0,0 +1,6 @@
+package com.revature.nested;
+
+public interface SimpleInterface {
+ double operate(double a, double b);
+
+}
diff --git a/day-5/target/classes/com/revature/nested/Driver.class b/day-5/target/classes/com/revature/nested/Driver.class
new file mode 100644
index 0000000..1c5af00
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/Driver.class differ
diff --git a/day-5/target/classes/com/revature/nested/LongTester.class b/day-5/target/classes/com/revature/nested/LongTester.class
new file mode 100644
index 0000000..5fea7a6
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/LongTester.class differ
diff --git a/day-5/target/classes/com/revature/nested/Outerclass$Innerclass.class b/day-5/target/classes/com/revature/nested/Outerclass$Innerclass.class
new file mode 100644
index 0000000..8c48f5c
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/Outerclass$Innerclass.class differ
diff --git a/day-5/target/classes/com/revature/nested/Outerclass$StaticInnerclass.class b/day-5/target/classes/com/revature/nested/Outerclass$StaticInnerclass.class
new file mode 100644
index 0000000..13c5d1d
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/Outerclass$StaticInnerclass.class differ
diff --git a/day-5/target/classes/com/revature/nested/Outerclass.class b/day-5/target/classes/com/revature/nested/Outerclass.class
new file mode 100644
index 0000000..66e9e59
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/Outerclass.class differ
diff --git a/day-5/target/classes/com/revature/nested/Printable.class b/day-5/target/classes/com/revature/nested/Printable.class
new file mode 100644
index 0000000..02e3895
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/Printable.class differ
diff --git a/day-5/target/classes/com/revature/nested/SimpleAbstractClass.class b/day-5/target/classes/com/revature/nested/SimpleAbstractClass.class
new file mode 100644
index 0000000..b46982f
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/SimpleAbstractClass.class differ
diff --git a/day-5/target/classes/com/revature/nested/SimpleInterface.class b/day-5/target/classes/com/revature/nested/SimpleInterface.class
new file mode 100644
index 0000000..bd0184e
Binary files /dev/null and b/day-5/target/classes/com/revature/nested/SimpleInterface.class differ
diff --git a/decrypter/.idea/.gitignore b/decrypter/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/decrypter/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/decrypter/.idea/compiler.xml b/decrypter/.idea/compiler.xml
new file mode 100644
index 0000000..308627b
--- /dev/null
+++ b/decrypter/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decrypter/.idea/jarRepositories.xml b/decrypter/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/decrypter/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decrypter/.idea/misc.xml b/decrypter/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/decrypter/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decrypter/.idea/vcs.xml b/decrypter/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/decrypter/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decrypter/decrypter.iml b/decrypter/decrypter.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/decrypter/decrypter.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/decrypter/pom.xml b/decrypter/pom.xml
new file mode 100644
index 0000000..4ec1da8
--- /dev/null
+++ b/decrypter/pom.xml
@@ -0,0 +1,23 @@
+
+
+ 4.0.0
+
+ com.revature
+ decrypter
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+
+
+
+ org.postgresql
+ postgresql
+ 42.2.12
+
+
+
+
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/Decrypter.java b/decrypter/src/main/java/com/revature/Decrypter.java
new file mode 100644
index 0000000..12b68ac
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/Decrypter.java
@@ -0,0 +1,20 @@
+package com.revature;
+
+import com.revature.util.AppState;
+
+public class Decrypter {
+
+ private static AppState app = new AppState();
+
+ public static void main(String[] args) {
+
+ while (app.isAppRunning()) {
+ app.getRouter().navigate("/home");
+ }
+ }
+
+ public static AppState app() {
+ return app;
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/exceptions/AuthenticationException.java b/decrypter/src/main/java/com/revature/exceptions/AuthenticationException.java
new file mode 100644
index 0000000..76d2028
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/exceptions/AuthenticationException.java
@@ -0,0 +1,9 @@
+package com.revature.exceptions;
+
+public class AuthenticationException extends RuntimeException {
+
+ public AuthenticationException() {
+ super("Authentication failed!");
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/exceptions/InvalidRequestException.java b/decrypter/src/main/java/com/revature/exceptions/InvalidRequestException.java
new file mode 100644
index 0000000..674c6fe
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/exceptions/InvalidRequestException.java
@@ -0,0 +1,13 @@
+package com.revature.exceptions;
+
+public class InvalidRequestException extends RuntimeException {
+
+ public InvalidRequestException() {
+ super("Invalid request made!");
+ }
+
+ public InvalidRequestException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/exceptions/ResourcePersistenceException.java b/decrypter/src/main/java/com/revature/exceptions/ResourcePersistenceException.java
new file mode 100644
index 0000000..9718cf7
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/exceptions/ResourcePersistenceException.java
@@ -0,0 +1,9 @@
+package com.revature.exceptions;
+
+public class ResourcePersistenceException extends RuntimeException {
+
+ public ResourcePersistenceException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/models/AppUser.java b/decrypter/src/main/java/com/revature/models/AppUser.java
new file mode 100644
index 0000000..98c1039
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/models/AppUser.java
@@ -0,0 +1,118 @@
+package com.revature.models;
+
+import java.util.Objects;
+
+public class AppUser {
+
+ private int id;
+ private String firstName;
+ private String lastName;
+ private String username;
+ private String password;
+ private UserRole userRole;
+
+ public AppUser() {
+ super();
+ }
+
+ public AppUser(AppUser copy) {
+ this.id = copy.id;
+ this.firstName = copy.firstName;
+ this.lastName = copy.lastName;
+ this.username = copy.username;
+ this.password = copy.password;
+ this.userRole = copy.userRole;
+ }
+
+ public AppUser(String firstName, String lastName, String username, String password) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.username = username;
+ this.password = password;
+ }
+
+ public AppUser(int id, String firstName, String lastName, String username, String password, UserRole userRole) {
+ this(firstName, lastName, username, password);
+ this.id = id;
+ this.userRole = userRole;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public UserRole getUserRole() {
+ return userRole;
+ }
+
+ public void setUserRole(UserRole userRole) {
+ this.userRole = userRole;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AppUser appUser = (AppUser) o;
+ return id == appUser.id &&
+ Objects.equals(firstName, appUser.firstName) &&
+ Objects.equals(lastName, appUser.lastName) &&
+ Objects.equals(username, appUser.username) &&
+ Objects.equals(password, appUser.password) &&
+ userRole == appUser.userRole;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, firstName, lastName, username, password, userRole);
+ }
+
+ @Override
+ public String toString() {
+ return "AppUser{" +
+ "id=" + id +
+ ", firstName='" + firstName + '\'' +
+ ", lastName='" + lastName + '\'' +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", userRole=" + userRole +
+ '}';
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/models/UserRole.java b/decrypter/src/main/java/com/revature/models/UserRole.java
new file mode 100644
index 0000000..fae0a24
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/models/UserRole.java
@@ -0,0 +1,11 @@
+package com.revature.models;
+
+public enum UserRole {
+ ADMIN,BASIC_USER,PREMIUM_USER;
+
+
+
+
+}
+
+
diff --git a/decrypter/src/main/java/com/revature/repos/CrudRepository.java b/decrypter/src/main/java/com/revature/repos/CrudRepository.java
new file mode 100644
index 0000000..f951083
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/repos/CrudRepository.java
@@ -0,0 +1,14 @@
+package com.revature.repos;
+
+import com.revature.util.LinkedList;
+import com.revature.util.Set;
+
+public interface CrudRepository {
+
+ void save(T newObj);
+ LinkedList findAll();
+ T findById(int id);
+ boolean update(T updatedObj);
+ boolean deleteById(int id);
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/repos/UserRepository.java b/decrypter/src/main/java/com/revature/repos/UserRepository.java
new file mode 100644
index 0000000..2d66b4b
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/repos/UserRepository.java
@@ -0,0 +1,148 @@
+package com.revature.repos;
+
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+import com.revature.util.ConnectionFactory;
+import com.revature.util.LinkedList;
+import com.revature.util.Set;
+
+import java.sql.*;
+
+import static com.revature.Decrypter.app;
+
+public class UserRepository implements CrudRepository{
+
+ private final String base = "SELECT * " +
+ "FROM app_users au " +
+ "JOIN user_roles ur " +
+ "USING (role_id) ";
+
+ public AppUser findUserByUsernameAndPassword(String username, String password) {
+
+ AppUser user = null;
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE username = ? AND password = ? ";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setString(1, username);
+ pstmt.setString(2, password);
+
+ ResultSet rs = pstmt.executeQuery();
+ user = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return user;
+
+ }
+
+ public AppUser findUserByUsername(String username) {
+
+ AppUser user = null;
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = base + "WHERE username = ?";
+ PreparedStatement pstmt = conn.prepareStatement(sql);
+ pstmt.setString(1, username);
+
+ ResultSet rs = pstmt.executeQuery();
+ user = mapResultSet(rs).pop();
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return user;
+
+ }
+
+ @Override
+ public void save(AppUser newObj) {
+
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+
+ String sql = "INSERT INTO app_users (username, password, first_name, last_name, role_id) " +
+ "VALUES (?, ?, ?, ?, ?)";
+
+ PreparedStatement pstmt = conn.prepareStatement(sql, new String[] {"user_id"});
+ pstmt.setString(1, newObj.getUsername());
+ pstmt.setString(2, newObj.getPassword());
+ pstmt.setString(3, newObj.getFirstName());
+ pstmt.setString(4, newObj.getLastName());
+ pstmt.setInt(5, newObj.getUserRole().ordinal() + 1);
+
+ int rowsInserted = pstmt.executeUpdate();
+
+ if (rowsInserted != 0) {
+ ResultSet rs = pstmt.getGeneratedKeys();
+ while (rs.next()) {
+ newObj.setId(rs.getInt("user_id"));
+ }
+ }
+
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public LinkedList findAll() {
+
+ Connection conn = app().getCurrentSession().getConnection();
+ LinkedList users = new LinkedList<>();
+
+ try {
+
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(base);
+ users = mapResultSet(rs);
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return users;
+ }
+
+ @Override
+ public AppUser findById(int id) {
+ System.err.println("Not implemented");
+ return null;
+ }
+
+ @Override
+ public boolean update(AppUser updatedObj) {
+ System.err.println("Not implemented");
+ return false;
+ }
+
+ @Override
+ public boolean deleteById(int id) {
+ System.err.println("Not implemented");
+ return false;
+ }
+
+ private LinkedList mapResultSet(ResultSet rs) throws SQLException {
+
+ LinkedList users = new LinkedList<>();
+
+ while(rs.next()) {
+ AppUser user = new AppUser();
+ user.setId(rs.getInt("user_id"));
+ user.setFirstName(rs.getString("first_name"));
+ user.setLastName(rs.getString("last_name"));
+ user.setUsername(rs.getString("username"));
+ user.setPassword(rs.getString("password"));
+ user.setUserRole(UserRole.valueOf(rs.getString("role_name")));
+ users.insert(user);
+ }
+
+ return users;
+
+ }
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/screens/HomeScreen.java b/decrypter/src/main/java/com/revature/screens/HomeScreen.java
new file mode 100644
index 0000000..0864b71
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/screens/HomeScreen.java
@@ -0,0 +1,50 @@
+package com.revature.screens;
+
+import static com.revature.Decrypter.app;
+
+public class HomeScreen extends Screen {
+
+ public HomeScreen() {
+ super("HomeScreen", "/home");
+ }
+
+ @Override
+ public void render() {
+
+ System.out.println("Welcome to Decrypter!\n");
+ System.out.println("1) Login");
+ System.out.println("2) Register");
+ System.out.println("3) Exit application");
+
+ try {
+
+ System.out.print("> ");
+ String userSelection = app().getConsole().readLine();
+
+ switch (userSelection) {
+ case "1":
+ System.out.println("Navigating to login screen");
+ app().getRouter().navigate("/login");
+ break;
+ case "2":
+ System.out.println("Navigating to register screen");
+ app().getRouter().navigate("/register");
+ break;
+ case "3":
+ System.out.println("Exiting application");
+ app().setAppRunning(false);
+ break;
+ default:
+ System.out.println("Invalid selection!");
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("Shutting down application");
+ app().setAppRunning(false);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/screens/LoginScreen.java b/decrypter/src/main/java/com/revature/screens/LoginScreen.java
new file mode 100644
index 0000000..f37811b
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/screens/LoginScreen.java
@@ -0,0 +1,51 @@
+package com.revature.screens;
+
+import com.revature.exceptions.InvalidRequestException;
+import com.revature.models.AppUser;
+import com.revature.services.UserService;
+
+import javax.security.sasl.AuthenticationException;
+
+import static com.revature.Decrypter.app;
+
+public class LoginScreen extends Screen {
+
+ private UserService userService;
+
+ public LoginScreen(UserService userService) {
+ super("LoginScreen", "/login");
+ this.userService = userService;
+ }
+
+ @Override
+ public void render() {
+ String username;
+ String password;
+
+ try {
+
+ System.out.println("+---------------------+");
+ System.out.println("Please provide your login credentials");
+ System.out.print("Username: ");
+ username = app().getConsole().readLine();
+ System.out.print("Password: ");
+ password = app().getConsole().readLine();
+
+ userService.authenticate(username, password);
+
+ if (app().isSessionValid()) {
+ System.out.println("[LOG] - Login successful, navigating to dashboard...");
+// app().getRouter().navigate("/dashboard");
+ }
+
+ } catch (InvalidRequestException | AuthenticationException e) {
+ System.err.println("[INFO] - Invalid login credentials provided!");
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("[SEVERE] - An unexpected exception occurred");
+ System.err.println("[FATAL] - Shutting down application");
+ app().setAppRunning(false);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/screens/RegisterScreen.java b/decrypter/src/main/java/com/revature/screens/RegisterScreen.java
new file mode 100644
index 0000000..58356bb
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/screens/RegisterScreen.java
@@ -0,0 +1,46 @@
+package com.revature.screens;
+
+import com.revature.models.AppUser;
+import com.revature.services.UserService;
+
+import static com.revature.Decrypter.app;
+
+public class RegisterScreen extends Screen {
+
+ private UserService userService;
+
+ public RegisterScreen(UserService userService) {
+ super("RegisterScreen", "/register");
+ this.userService = userService;
+ }
+
+ @Override
+ public void render() {
+
+ String firstName;
+ String lastName;
+ String username;
+ String password;
+
+ try {
+
+ System.out.println("+---------------------+");
+ System.out.println("Sign up for a new account!");
+ System.out.print("First name: ");
+ firstName = app().getConsole().readLine();
+ System.out.print("Last name: ");
+ lastName = app().getConsole().readLine();
+ System.out.print("Username: ");
+ username = app().getConsole().readLine();
+ System.out.print("Password: ");
+ password = app().getConsole().readLine();
+
+ AppUser newUser = new AppUser(firstName, lastName, username, password);
+
+ userService.register(newUser);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/screens/Screen.java b/decrypter/src/main/java/com/revature/screens/Screen.java
new file mode 100644
index 0000000..fc373a1
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/screens/Screen.java
@@ -0,0 +1,23 @@
+package com.revature.screens;
+
+public abstract class Screen {
+
+ protected String name;
+ protected String route;
+
+ public Screen(String name, String route) {
+ this.name = name;
+ this.route = route;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getRoute() {
+ return route;
+ }
+
+ public abstract void render();
+
+}
diff --git a/decrypter/src/main/java/com/revature/services/UserService.java b/decrypter/src/main/java/com/revature/services/UserService.java
new file mode 100644
index 0000000..f30e4b5
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/services/UserService.java
@@ -0,0 +1,65 @@
+package com.revature.services;
+
+import com.revature.exceptions.AuthenticationException;
+import com.revature.exceptions.InvalidRequestException;
+import com.revature.exceptions.ResourcePersistenceException;
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+import com.revature.repos.UserRepository;
+import com.revature.util.ConnectionFactory;
+import com.revature.util.Session;
+
+import java.sql.Connection;
+
+import static com.revature.Decrypter.app;
+
+public class UserService {
+
+ private UserRepository userRepo;
+
+ public UserService(UserRepository userRepo) {
+ this.userRepo = userRepo;
+ }
+
+ public void authenticate(String username, String password) {
+
+ if (username == null || username.trim().equals("") || password == null || password.trim().equals("")) {
+ throw new InvalidRequestException("Invalid credentials provided (null or empty strings)!");
+ }
+
+ AppUser authUser = userRepo.findUserByUsernameAndPassword(username, password);
+
+ if (authUser == null) {
+ throw new AuthenticationException();
+ }
+
+ app().setCurrentSession(new Session(authUser, ConnectionFactory.getInstance().getConnection()));
+
+ }
+
+ public void register(AppUser newUser) {
+
+ if (!isUserValid(newUser)){
+ throw new InvalidRequestException("Invalid new user provided!");
+ }
+
+ if (userRepo.findUserByUsername(newUser.getUsername()) != null) {
+ throw new ResourcePersistenceException("The provided username is already in use!");
+ }
+
+ newUser.setUserRole(UserRole.BASIC_USER);
+ userRepo.save(newUser);
+
+ }
+
+ public boolean isUserValid(AppUser user) {
+ if (user == null) return false;
+ if (user.getFirstName() == null || user.getFirstName().trim().equals("")) return false;
+ if (user.getLastName() == null || user.getLastName().trim().equals("")) return false;
+ if (user.getUsername() == null || user.getUsername().trim().equals("")) return false;
+ if (user.getPassword() == null || user.getPassword().trim().equals("")) return false;
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/AppState.java b/decrypter/src/main/java/com/revature/util/AppState.java
new file mode 100644
index 0000000..6e16c7e
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/AppState.java
@@ -0,0 +1,71 @@
+package com.revature.util;
+
+import com.revature.repos.UserRepository;
+import com.revature.screens.HomeScreen;
+import com.revature.screens.LoginScreen;
+import com.revature.screens.RegisterScreen;
+import com.revature.services.UserService;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+public class AppState {
+
+ private BufferedReader console;
+ private ScreenRouter router;
+ private Session currentSession;
+ private boolean appRunning;
+
+ public AppState() {
+
+ System.out.println("[LOG] - Initializing application...");
+
+ this.appRunning = true;
+ this.console = new BufferedReader(new InputStreamReader(System.in));
+
+ final UserRepository userRepo = new UserRepository();
+
+ final UserService userService = new UserService(userRepo);
+
+ router = new ScreenRouter();
+ router.addScreen(new HomeScreen())
+ .addScreen(new RegisterScreen(userService))
+ .addScreen(new LoginScreen(userService));
+
+ System.out.println("[LOG] - Application initialized");
+
+ }
+
+ public BufferedReader getConsole() {
+ return console;
+ }
+
+ public ScreenRouter getRouter() {
+ return router;
+ }
+
+ public boolean isAppRunning() {
+ return appRunning;
+ }
+
+ public void setAppRunning(boolean appRunning) {
+ this.appRunning = appRunning;
+ }
+
+ public Session getCurrentSession() {
+ return currentSession;
+ }
+
+ public void setCurrentSession(Session currentSession) {
+ this.currentSession = currentSession;
+ }
+
+ public void invalidateCurrentSession() {
+ this.currentSession = null;
+ }
+
+ public boolean isSessionValid() {
+ return (this.currentSession != null);
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/ConnectionFactory.java b/decrypter/src/main/java/com/revature/util/ConnectionFactory.java
new file mode 100644
index 0000000..e5911be
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/ConnectionFactory.java
@@ -0,0 +1,56 @@
+package com.revature.util;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionFactory {
+
+ private static ConnectionFactory connFactory = new ConnectionFactory();
+
+ private Properties props = new Properties();
+
+ static {
+ try {
+ Class.forName("org.postgresql.Driver");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private ConnectionFactory() {
+ try {
+ props.load(new FileReader("src/main/resources/application.properties"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static ConnectionFactory getInstance() {
+ return connFactory;
+ }
+
+ public Connection getConnection() {
+
+ Connection conn = null;
+
+ try {
+
+ conn = DriverManager.getConnection(
+ props.getProperty("url"),
+ props.getProperty("admin-usr"),
+ props.getProperty("admin-pw")
+ );
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return conn;
+
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/LinkedList.java b/decrypter/src/main/java/com/revature/util/LinkedList.java
new file mode 100644
index 0000000..04c7078
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/LinkedList.java
@@ -0,0 +1,116 @@
+package com.revature.util;
+
+import com.revature.models.AppUser;
+
+public class LinkedList {
+
+ private int size;
+ private Node head;
+ private Node tail;
+
+ public T findFirst(T data) {
+
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ if (currentNode.data.equals(data)) {
+ return currentNode.data;
+ }
+ }
+
+ return null;
+
+ }
+
+ public void insert(T data) {
+
+ if (data == null) {
+ return;
+ }
+
+ Node newNode = new Node<>(data);
+ if (head == null) {
+ tail = head = newNode;
+ } else {
+ tail.nextNode = newNode;
+ newNode.prevNode = tail;
+ tail = newNode;
+ }
+
+ size++;
+
+ }
+
+ public T pop() {
+
+ if (head == null) {
+ return null;
+ }
+
+ T popped = head.data;
+ head = head.nextNode;
+
+ if (head != null) {
+ head.prevNode = null;
+ }
+
+ size--;
+
+ return popped;
+
+ }
+
+ public T peek() {
+ return (head == null) ? null : head.data;
+ }
+
+ public boolean contains(T data) {
+
+ if (data == null) {
+ return false;
+ }
+
+ // Consensus dictates we should go with the for...because it makes people feel better. lol
+// Node currentNode = head;
+// while (currentNode != null) {
+// if (currentNode.data.equals(data)) {
+// return true;
+// }
+// currentNode = currentNode.nextNode;
+// }
+
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ if (currentNode.data.equals(data)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public void printList() {
+ for (Node currentNode = head; currentNode != null; currentNode = currentNode.nextNode) {
+ System.out.println(currentNode.data);
+ }
+ }
+
+ private static class Node {
+ T data;
+ Node nextNode;
+ Node prevNode;
+
+ Node(T data) {
+ this.data = data;
+ }
+
+ Node(T data, Node nextNode, Node prevNode) {
+ this(data);
+ this.nextNode = nextNode;
+ this.prevNode = prevNode;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/Map.java b/decrypter/src/main/java/com/revature/util/Map.java
new file mode 100644
index 0000000..497ff68
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/Map.java
@@ -0,0 +1,166 @@
+package com.revature.util;
+
+import java.util.Arrays;
+
+public class Map {
+
+ private int size;
+ private final int DEFAULT_CAPACITY = 16;
+
+ @SuppressWarnings("unchecked")
+ private Entry[] entries = new Entry[DEFAULT_CAPACITY];
+
+ public boolean containsKey(K key) {
+ for (int i = 0; i < size; i++) {
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ return true;
+ }
+ } else if (entries[i].key.equals(key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public LinkedList keyList() {
+ LinkedList keyList = new LinkedList<>();
+ for (int i = 0; i < size; i++) {
+ keyList.insert(entries[i].key);
+ }
+ return keyList;
+ }
+
+ public V get(K key) {
+ for (int i = 0; i < size; i++) {
+
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ return entries[i].value;
+ }
+ } else if (entries[i].key.equals(key)) {
+ return entries[i].value;
+ }
+
+ }
+ return null;
+ }
+
+ public V getOrDefault(K key, V defaultValue) {
+
+ if (!containsKey(key)) {
+ return defaultValue;
+ }
+
+ return get(key);
+
+ }
+
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Adds a new entry to the map using the provided key and value. Returns the
+ * value previously associated with the key. If the key was not in the map prior,
+ * returns null.
+ *
+ * @param key
+ * @param value
+ * @return the previous value associated with the key, could return null
+ */
+ public V put(K key, V value) {
+
+ V previousValue = null;
+
+ boolean wasInserted = true;
+ for (int i = 0; i < size; i++) {
+
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ previousValue = entries[i].value;
+ entries[i].value = value;
+ wasInserted = false;
+ break;
+ }
+ } else if (entries[i].key.equals(key)) {
+ previousValue = entries[i].value;
+ entries[i].value = value;
+ wasInserted = false;
+ break;
+ }
+
+ }
+
+ if (wasInserted) {
+ ensureCapacity();
+ entries[size++] = new Entry<>(key, value);
+ }
+
+ return previousValue;
+
+ }
+
+ public void remove(K key) {
+
+ boolean wasRemoved = false;
+ for (int i = 0; i < size; i++) {
+ if (entries[i].key == null) {
+ if (entries[i].key == key) {
+ entries[i] = entries[size - 1];
+ size--;
+ wasRemoved = true;
+ }
+ } else if (entries[i].key.equals(key)) {
+ entries[i] = entries[size - 1];
+ size--;
+ wasRemoved = true;
+ }
+ }
+
+ if (wasRemoved) {
+ condenseArray();
+ }
+
+ }
+
+ public int size() {
+ return size;
+ }
+
+ // this method will be helpful after putting new entries into the map
+ private void ensureCapacity() {
+ if (size == entries.length) {
+ entries = Arrays.copyOf(entries, entries.length * 2);
+ }
+ }
+
+ // this method will be helpful after removing a key from the map
+ private void condenseArray() {
+ if (size * 2 < entries.length) {
+ entries = Arrays.copyOf(entries, entries.length / 2);
+ }
+ }
+
+ private static class Entry {
+
+ private final K key;
+ private V value;
+
+ public Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry{" +
+ "key=" + key +
+ ", value=" + value +
+ '}';
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/ScreenRouter.java b/decrypter/src/main/java/com/revature/util/ScreenRouter.java
new file mode 100644
index 0000000..2765324
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/ScreenRouter.java
@@ -0,0 +1,43 @@
+package com.revature.util;
+
+import com.revature.screens.Screen;
+
+public class ScreenRouter {
+
+ private Set screens = new Set<>();
+
+ public Set getScreens() {
+ return screens;
+ }
+
+ public ScreenRouter addScreen(Screen screen) {
+ System.out.println("[LOG] - Loading " + screen.getName() + " into router");
+ screens.add(screen);
+ return this;
+ }
+
+ // TODO clean this nastiness...implement a Set data structure
+ public void navigate(String route) {
+
+ for (Screen screen : screens.toArray(Screen.class)) {
+ if (screen.getRoute().equals(route)) {
+ screen.render();
+ }
+ }
+
+ // leaving this for posterity
+// LinkedList tempScreens = new LinkedList<>();
+// Screen currentScreen = screens.pop();
+//
+// while (currentScreen != null) {
+// tempScreens.insert(currentScreen);
+// if (currentScreen.getRoute().equals(route)) {
+// currentScreen.render();
+// }
+// currentScreen = screens.pop();
+// }
+// screens = tempScreens;
+
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/Session.java b/decrypter/src/main/java/com/revature/util/Session.java
new file mode 100644
index 0000000..a3d514e
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/Session.java
@@ -0,0 +1,44 @@
+package com.revature.util;
+
+import com.revature.models.AppUser;
+import com.revature.models.UserRole;
+
+import java.sql.Connection;
+
+public class Session {
+
+ private AppUser sessionUser;
+ private Connection connection;
+
+ public Session(AppUser sessionUser, Connection connection) {
+
+ if (sessionUser == null || connection == null) {
+ throw new ExceptionInInitializerError("Cannot establish user session, null values provided!");
+ }
+
+ this.sessionUser = sessionUser;
+ this.connection = connection;
+
+ }
+
+ public AppUser getSessionUser() {
+ return sessionUser;
+ }
+
+ public void setSessionUser(AppUser sessionUser) {
+ this.sessionUser = sessionUser;
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public void setConnection(Connection connection) {
+ this.connection = connection;
+ }
+
+ public boolean isAdmin() {
+ return (sessionUser.getUserRole().equals(UserRole.ADMIN));
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/java/com/revature/util/Set.java b/decrypter/src/main/java/com/revature/util/Set.java
new file mode 100644
index 0000000..93f1b95
--- /dev/null
+++ b/decrypter/src/main/java/com/revature/util/Set.java
@@ -0,0 +1,46 @@
+package com.revature.util;
+
+import java.lang.reflect.Array;
+
+public class Set {
+
+ private Map map;
+
+ public Set() {
+ this.map = new Map<>();
+ }
+
+ public boolean add(T data) {
+ return this.map.put(data, data.hashCode()) == null;
+ }
+
+ public boolean contains(T data) {
+ return this.map.containsKey(data);
+ }
+
+ public boolean isEmpty() {
+ return this.map.isEmpty();
+ }
+
+ // TODO: probably should return something other than true all the time. maybe?
+ public boolean remove(T data) {
+ this.map.remove(data);
+ return true;
+ }
+
+ public int size() {
+ return this.map.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ public T[] toArray(Class clazz) {
+ LinkedList keys = this.map.keyList();
+ T[] keyArr = (T[]) Array.newInstance(clazz, size());
+ for (int i = 0; i < size(); i++) {
+ T t = keys.pop();
+ keyArr[i] = t;
+ }
+ return keyArr;
+ }
+
+}
\ No newline at end of file
diff --git a/decrypter/src/main/resources/application.properties b/decrypter/src/main/resources/application.properties
new file mode 100644
index 0000000..329cb32
--- /dev/null
+++ b/decrypter/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+url=jdbc:postgresql://revdatabase.c9yldontobdz.us-east-2.rds.amazonaws.com:5432/revdata
+admin-usr=username
+admin-pw=password
+
diff --git a/decrypter/src/main/resources/table-creation.sql b/decrypter/src/main/resources/table-creation.sql
new file mode 100644
index 0000000..53381e1
--- /dev/null
+++ b/decrypter/src/main/resources/table-creation.sql
@@ -0,0 +1,24 @@
+create table user_roles (
+ role_id serial,
+ role_name varchar(25) unique not null,
+
+ constraint user_roles_pk
+ primary key (role_id)
+);
+
+create table app_users (
+ user_id serial,
+ username varchar unique not null,
+ password varchar not null,
+ first_name varchar not null,
+ last_name varchar not null,
+ role_id int not null,
+
+ constraint app_users_pk
+ primary key (user_id),
+
+ constraint app_user_role_fk
+ foreign key (role_id)
+ references user_roles
+
+);
\ No newline at end of file
diff --git a/decrypter/src/test/java/com/revature/util/ConnectionFactoryTest.java b/decrypter/src/test/java/com/revature/util/ConnectionFactoryTest.java
new file mode 100644
index 0000000..8372f07
--- /dev/null
+++ b/decrypter/src/test/java/com/revature/util/ConnectionFactoryTest.java
@@ -0,0 +1,19 @@
+package com.revature.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class ConnectionFactoryTest {
+
+ public static void main(String[] args) {
+ try (Connection conn = ConnectionFactory.getInstance().getConnection()) {
+ if (conn == null) {
+ System.err.println("You didn't make a connection, noob.");
+ } else {
+ System.out.println("Ok so maybe you kinda know what you're doing.");
+ }
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/decrypter/src/test/java/com/revature/util/MapTest.java b/decrypter/src/test/java/com/revature/util/MapTest.java
new file mode 100644
index 0000000..eb0afcc
--- /dev/null
+++ b/decrypter/src/test/java/com/revature/util/MapTest.java
@@ -0,0 +1,37 @@
+package com.revature.util;
+
+public class MapTest {
+
+ public static void main(String[] args) {
+ Map mapTest = new Map<>();
+ mapTest.put("test1", 1);
+ System.out.println("size = " + mapTest.size());
+ mapTest.remove("test1");
+ System.out.println("size = " + mapTest.size());
+
+// mapTest.put("test2", 2);
+// mapTest.put("test3", 3);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of test1 = " + mapTest.get("test1"));
+// System.out.println("value of test2 = " + mapTest.get("test2"));
+// System.out.println("value of test3 = " + mapTest.get("test3"));
+//
+// mapTest.put("test1", -1);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of test1 = " + mapTest.get("test1"));
+//
+// mapTest.put(null, 0);
+// System.out.println("size = " + mapTest.size());
+// System.out.println("value of null = " + mapTest.get(null));
+//
+// System.out.println(mapTest.containsKey("test2"));
+// System.out.println(mapTest.containsKey(null));
+// System.out.println(mapTest.containsKey("fakeKey"));
+//
+// mapTest.put("nullVal", null);
+// System.out.println(mapTest.getOrDefault("nullVal", -5));
+// System.out.println(mapTest.containsKey(null));
+
+ }
+
+}
\ No newline at end of file
diff --git a/functional-java/pom.xml b/functional-java/pom.xml
new file mode 100644
index 0000000..d1334b4
--- /dev/null
+++ b/functional-java/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ com.example
+ functional-java
+ 1.0-SNAPSHOT
+
+
+ 1.8
+ 1.8
+
+
+
\ No newline at end of file
diff --git a/functional-java/src/main/java/com/revature/ComposingFunctionsDriver.java b/functional-java/src/main/java/com/revature/ComposingFunctionsDriver.java
new file mode 100644
index 0000000..e09644a
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/ComposingFunctionsDriver.java
@@ -0,0 +1,36 @@
+package com.revature;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public class ComposingFunctionsDriver {
+
+ public static void main(String[] args) {
+ Consumer c1 = s -> System.out.println("c1 is consuming " + s);
+ Consumer c2 = s -> System.out.println("c2 is consuming " + s);
+ Consumer c3 = c1.andThen(c2);
+
+ c3.accept("test string");
+
+ Predicate isNull= s->s==null;
+ Predicate isNotNull= s->s!=null;
+ Predicate isEmpty= s->s.trim().equals("");
+ Predicate p3= isNull.negate().and(isEmpty.negate());
+
+
+ List myStrings= Arrays.asList("one","two" , "three" , "four" , "five" , "six" , "seven" , "eight" ,"nine" );
+
+ Comparator cmp1=(s1,s2)->s1.compareTo(s2);
+
+ myStrings.sort(cmp1);
+ System.out.println(myStrings);
+
+
+
+ }
+
+
+}
diff --git a/functional-java/src/main/java/com/revature/Driver.java b/functional-java/src/main/java/com/revature/Driver.java
new file mode 100644
index 0000000..fea5f71
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/Driver.java
@@ -0,0 +1,95 @@
+package com.revature;
+
+import com.revature.models.Animal;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Supplier;
+
+public class Driver {
+
+ public static void main(String[] args) {
+
+ // Local anonymous class
+ // Can be a inline implementation of any abstract type (interface or abstact class)
+ // Local anon classes actually create another class file at compilation (making JAR size larger)
+ Animal newAnimal = new Animal() {
+ @Override
+ public void eat() {
+ System.out.println("slurp");
+ }
+
+ @Override
+ public void makeSound() {
+ System.out.println("waakkaaakkaaakaaa");
+ }
+ };
+
+// Animal wontWork = () -> {
+//
+// };
+
+ Thread t1 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("This is a local anonymous class that implements the Runnable interface.");
+ }
+ });
+
+ Thread t2 = new Thread(() -> {
+ System.out.println("This is a lambda expression that implements the Runnable interface.");
+ });
+
+ t1.start();
+ t2.start();
+
+ newAnimal.eat();
+ newAnimal.makeSound();
+
+ /*
+ Legal Lambda Expression Syntax
+ - (parameter) -> expression
+ - parameter -> expression
+ - parameter -> { code block of expressions }
+ - (parameter, parameter) -> expression
+ - (parameter, parameter) -> { code block of expressions }
+ - () -> expression
+ - () -> { code block of expressions }
+ */
+
+ // Lambda expressions are converted into private methods at compile time
+ Supplier stringSupplier = () -> "Something";
+ String someString = stringSupplier.get();
+ System.out.println(someString);
+
+ System.out.println("+--------------------+");
+
+ List strings = Arrays.asList("one", "two", "three", "four", "five");
+
+ // toString (kinda does what we want, but not really)
+ System.out.println(strings.toString());
+
+ System.out.println("+--------------------+");
+
+ // traditional for-loop
+ for (int i = 0; i < strings.size(); i++) {
+ System.out.println(strings.get(i));
+ }
+
+ // enhanced for-loop (for-each loop)
+ System.out.println("+--------------------+");
+ for (String s: strings) {
+ System.out.println(s);
+ }
+
+ System.out.println("+--------------------+");
+ // Iterable#forEach using a lambda expression
+ strings.forEach(str -> System.out.println(str));
+
+ System.out.println("+--------------------+");
+ // Iterable#forEach using a method reference
+ strings.forEach(System.out::println);
+
+ }
+
+}
\ No newline at end of file
diff --git a/functional-java/src/main/java/com/revature/FunctionalDriver.java b/functional-java/src/main/java/com/revature/FunctionalDriver.java
new file mode 100644
index 0000000..e1de5cc
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/FunctionalDriver.java
@@ -0,0 +1,132 @@
+package com.revature;
+
+import com.revature.models.User;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+public class FunctionalDriver {
+
+ public static void main(String[] args) {
+
+ /*
+ Java 8 introduced a package: java.util.function
+ - a set of functional interfaces
+ - there are more than 40 individual interfaces provided by this package
+ - organized into 4 main categories (there is a 5th we will discuss):
+ - Supplier
+ + T get();
+ + takes in no value; returns a value
+ - Consumer
+ + void accept(T val);
+ + takes in a value; returns no value
+ - Predicate
+ + boolean test(T val);
+ + takes in a value; returns a boolean
+ - Function
+ + T = the parameter, R = return type
+ + R apply(T val);
+ + takes in a value of type T, returns a value of type R
+ The fifth type of functional interface is not actually in the java.util.function
+ package. It comes from java.lang, and is the Runnable interface (since java 1.0)
+ + void run();
+ + takes in nothing; returns nothing
+ */
+
+ Supplier stringSupplier = () -> {
+ System.out.println("I am in the Supplier!");
+ return "Hi!";
+ };
+
+ String s = stringSupplier.get();
+ System.out.println(s);
+
+//---------------------------------------------------------------------
+
+ Consumer stringConsumer = str -> {
+ System.out.println("I am in the Consumer!");
+ System.out.println(str);
+ };
+
+ stringConsumer.accept("a string");
+
+
+ //------------------------------------------------------------------------
+
+ Predicate stringPredicate = str -> {
+ System.out.println("I am in the Predicate!");
+ return (str == null || str.trim().equals(""));
+ };
+
+ s = ".";
+ if (stringPredicate.test(s)) {
+ System.out.println("The provided string is null or empty");
+ } else {
+ System.out.println("The provided string is not null or empty");
+ }
+
+
+ // Gives us an immutable list?
+ List immutableStringList = Arrays.asList("one", "two", "three", "four", "five");
+
+ List oldWay = new ArrayList<>();
+ for (String str : immutableStringList) {
+ if (!(str.startsWith("t") || str.startsWith("T"))) {
+ oldWay.add(str);
+ }
+ }
+
+ for (String str : oldWay) {
+ System.out.println(str);
+ }
+ System.out.println("this is the old way");
+
+ System.out.println("+----------------------+");
+
+ List stringsThatDontStartWithT = immutableStringList.stream()
+ .filter(str -> !(str.startsWith("t") || str.startsWith("T")))
+ .collect(Collectors.toList());
+
+
+
+ // The original list is unchanged! (an important principle in functional programming)
+ immutableStringList.forEach(System.out::println);
+
+ System.out.println("+----------------------+");
+
+ // Contains only "one", "four", and "five"
+ stringsThatDontStartWithT.forEach(System.out::println);
+
+ System.out.println("+----------------------+");
+
+ Predicate startsWithT = str -> (str.startsWith("t") || str.startsWith("T"));
+
+ // throws an UnsupportedOperationException (because the way we created this list makes it immutable)
+// immutableStringList.removeIf(startsWithT);
+// immutableStringList.forEach(System.out::println);
+
+ // There are methods on the List interface (and other Collection types) that can take in predicates
+ // and manipulate the original collection
+ List mutableStringList = new ArrayList<>(Arrays.asList("one", "two", "three", "four", "five"));
+ mutableStringList.removeIf(startsWithT);
+ mutableStringList.forEach(System.out::println);
+
+ Function mapStringToUser_1 = str -> {
+ return new User(str);
+ };
+
+ Function mapStringToUser_2 = str -> new User(str);
+
+ Function mapStringToUser_3 = User::new;
+
+ User mappedUser = mapStringToUser_3.apply("Wezley");
+ System.out.println(mappedUser);
+
+ }
+}
\ No newline at end of file
diff --git a/functional-java/src/main/java/com/revature/PrimitiveFunctionDriver.java b/functional-java/src/main/java/com/revature/PrimitiveFunctionDriver.java
new file mode 100644
index 0000000..7001484
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/PrimitiveFunctionDriver.java
@@ -0,0 +1,30 @@
+package com.revature;
+
+import java.util.function.DoubleToIntFunction;
+import java.util.function.IntSupplier;
+import java.util.function.Supplier;
+
+
+
+/*
+
+ */
+public class PrimitiveFunctionDriver {
+
+ public static void main(String[] args){
+ Supplier integerSupplier = () ->10; //<-that 10, gets autobox4ed into an Integer
+ //VV here that autoboxed Integer is now re-converted back into a primitive int
+ int i1=integerSupplier.get();
+ System.out.println("i1= "+integerSupplier);
+
+ //No inheritace relationship between primitive-functional interfaces and the main types
+ IntSupplier intSupplier= ()->10;
+ int i2=intSupplier.getAsInt();
+ System.out.println("i2= "+intSupplier);
+
+
+ DoubleToIntFunction doubleToIntFunction=value -> (int)Math.floor(value);
+ int e=doubleToIntFunction.applyAsInt(2.71828);
+ System.out.println("e= "+e);
+ }
+}
diff --git a/functional-java/src/main/java/com/revature/models/Animal.java b/functional-java/src/main/java/com/revature/models/Animal.java
new file mode 100644
index 0000000..471f484
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/models/Animal.java
@@ -0,0 +1,8 @@
+package com.revature.models;
+
+public abstract class Animal {
+
+ public abstract void eat();
+ public abstract void makeSound();
+
+}
\ No newline at end of file
diff --git a/functional-java/src/main/java/com/revature/models/Dog.java b/functional-java/src/main/java/com/revature/models/Dog.java
new file mode 100644
index 0000000..247a47c
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/models/Dog.java
@@ -0,0 +1,15 @@
+package com.revature.models;
+
+public class Dog extends Animal {
+
+ @Override
+ public void eat() {
+ System.out.println("Nom nom nom");
+ }
+
+ @Override
+ public void makeSound() {
+ System.out.println("Woof ruff bark");
+ }
+
+}
\ No newline at end of file
diff --git a/functional-java/src/main/java/com/revature/models/User.java b/functional-java/src/main/java/com/revature/models/User.java
new file mode 100644
index 0000000..82ec159
--- /dev/null
+++ b/functional-java/src/main/java/com/revature/models/User.java
@@ -0,0 +1,31 @@
+package com.revature.models;
+
+public class User {
+
+ private String name;
+
+ public User(String name) {
+ this.name = name;
+ }
+
+ public User(int i) {
+ // included this to see if the compiler is smart enough to deduce with constructor
+ // to invoke if using a method reference
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+
+}
\ No newline at end of file
diff --git a/project_0/pom.xml b/project_0/pom.xml
new file mode 100644
index 0000000..dad6905
--- /dev/null
+++ b/project_0/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ com.example
+ project_0
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file