diff --git a/.idea/IntelliLang.xml b/.idea/IntelliLang.xml
new file mode 100644
index 0000000..b223a1b
--- /dev/null
+++ b/.idea/IntelliLang.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ AsyncQueryRunner (org.apache.commons.dbutils)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Jodd (jodd.db)
+
+
+
+
+
+
+
+ MyBatis @Select/@Delete/@Insert/@Update
+
+
+
+
+
+
+
+ QueryRunner (org.apache.commons.dbutils)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ R2DBC (io.r2dbc)
+
+
+
+
+
+ Reactiverse Postgres Client (io.reactiverse)
+
+
+
+
+
+
+
+
+
+
+
+
+ SmallRye Axle SqlClient (io.vertx.axle.sqlclient)
+
+
+
+
+
+ SmallRye Mutiny SqlClient (io.vertx.mutiny.sqlclient)
+
+
+
+
+
+ SmallRye Mutiny SqlConnection (io.vertx.mutiny.sqlclient)
+
+
+
+
+
+
+
+ Vert.x SQL Extensions (io.vertx.ext.sql)
+
+
+
+
+
+
+ Vert.x SQL Reactive Extensions (io.vertx.reactivex.ext.sql)
+
+
+
+
+
+
+
+
+
+ Vert.x SqlClient (io.vertx.sqlclient)
+
+
+
+
+
+
+
+
+
+
+ Vert.x SqlClient RxJava2 (io.vertx.reactivex.sqlclient)
+
+
+
+
+
+
+
+
+
+
+
+ jOOQ (org.jooq.DSLContext)
+
+
+
+
+
+
+
+ rxjava2-jdbc (org.davidmoten.rx.jdbc)
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/BankAccount.java b/src/Lecture4_interfaces_abstract_classes/BankAccount.java
index 28d0d07..c935271 100644
--- a/src/Lecture4_interfaces_abstract_classes/BankAccount.java
+++ b/src/Lecture4_interfaces_abstract_classes/BankAccount.java
@@ -1,7 +1,9 @@
package Lecture4_interfaces_abstract_classes;
public class BankAccount {
+
private double balance;
+
public BankAccount(double balance) {
this.balance = balance;
}
@@ -13,4 +15,4 @@ public double getBalance() {
public void setBalance(double balance) {
this.balance = balance;
}
-}
+}
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java
index ed81eb8..0602c16 100644
--- a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java
+++ b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java
@@ -1,51 +1,45 @@
package Lecture4_interfaces_abstract_classes;
-import org.jetbrains.annotations.NotNull;
-
import java.util.Calendar;
public abstract class BaseTransaction implements TransactionInterface {
+
private final int amount;
private final Calendar date;
private final String transactionID;
- /**
- * Lecture1_adt.TransactionInterface Constructor
- * @param amount in an integer
- * @param date: Not null, and must be a Calendar object
- * @return void
- * Instialises the field, attributes of a transaction
- * Creates a object of this
- */
- public BaseTransaction(int amount, @NotNull Calendar date) {
+ public BaseTransaction(int amount, Calendar date) {
this.amount = amount;
this.date = (Calendar) date.clone();
- int uniq = (int) Math.random()*10000;
- transactionID = date.toString()+uniq;
+ int uniq = (int) (Math.random() * 10000);
+ this.transactionID = date.getTimeInMillis() + "-" + uniq;
}
- /**
- * getAmount()
- * @return integer
- */
+ @Override
public double getAmount() {
- return amount; // Because we are dealing with Value types we need not worry about what we return
+ return amount;
}
- /**
- * getDate()
- * @return Calendar Object
- */
+ @Override
public Calendar getDate() {
-// return date; // Because we are dealing with Reference types we need to judiciously copy what our getters return
- return (Calendar) date.clone(); // Defensive copying or Judicious Copying
+ return (Calendar) date.clone();
+ }
+
+ @Override
+ public String getTransactionID() {
+ return transactionID;
+ }
+
+ @Override
+ public void printTransactionDetails() {
+ System.out.println("--- Transaction Details ---");
+ System.out.println("Transaction ID: " + transactionID);
+ System.out.println("Date: " + date.getTime());
+ System.out.println("Amount: " + amount);
}
- // Method to get a unique identifier for the transaction
- public String getTransactionID(){
- return transactionID;
+ @Override
+ public void apply(BankAccount ba) throws InsufficientFundsException {
+ System.out.println("Base transaction executed.");
}
- // Method to print a transaction receipt or details
- public abstract void printTransactionDetails();
- public abstract void apply(BankAccount ba);
-}
+}
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java
index 81afab5..f8c0442 100644
--- a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java
+++ b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java
@@ -1,30 +1,36 @@
package Lecture4_interfaces_abstract_classes;
import org.jetbrains.annotations.NotNull;
-
import java.util.Calendar;
public class DepositTrasaction extends BaseTransaction {
+
public DepositTrasaction(int amount, @NotNull Calendar date){
super(amount, date);
}
+
private boolean checkDepositAmount(int amt){
if (amt < 0){
- return false;
+ return false;
}
else{
- return true;
+ return true;
}
}
- // Method to print a transaction receipt or details
+ @Override
public void printTransactionDetails(){
- System.out.println("Deposit Trasaction: "+this.toString());
+ System.out.println("--- Deposit Transaction ---");
+ System.out.println("Transaction ID: " + getTransactionID());
+ System.out.println("Date: " + getDate().getTime());
+ System.out.println("Amount Deposited: " + getAmount());
}
- public void apply(BankAccount ba){
+ // Added 'throws InsufficientFundsException' to maintain signature compatibility
+ @Override
+ public void apply(BankAccount ba) throws InsufficientFundsException {
double curr_balance = ba.getBalance();
double new_balance = curr_balance + getAmount();
ba.setBalance(new_balance);
}
-}
+}
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java
new file mode 100644
index 0000000..cf48eef
--- /dev/null
+++ b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java
@@ -0,0 +1,20 @@
+package Lecture4_interfaces_abstract_classes;
+
+public class InsufficientFundsException extends Exception {
+
+ private double deficitAmount;
+
+ public InsufficientFundsException(String message, double deficit) {
+ super(message);
+ this.deficitAmount = deficit;
+ }
+
+ public InsufficientFundsException(String message) {
+ super(message);
+ this.deficitAmount = 0.0;
+ }
+
+ public double getDeficitAmount() {
+ return deficitAmount;
+ }
+}
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java b/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java
index 5902713..7bdeaf0 100644
--- a/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java
+++ b/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java
@@ -1,21 +1,16 @@
package Lecture4_interfaces_abstract_classes;
+
import java.util.Calendar;
-/**
- * Interface for Transactions
- * Any class that defines a transaction is expected to implement this Interface
- */
public interface TransactionInterface {
- // Method to get the transaction amount
double getAmount();
- // Method to get the transaction date
Calendar getDate();
- // Method to get a unique identifier for the transaction
String getTransactionID();
-}
-
+ void apply(BankAccount ba) throws InsufficientFundsException;
+ void printTransactionDetails();
+}
\ No newline at end of file
diff --git a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java
index face5b6..7406cba 100644
--- a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java
+++ b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java
@@ -1,10 +1,13 @@
package Lecture4_interfaces_abstract_classes;
import org.jetbrains.annotations.NotNull;
-
import java.util.Calendar;
public class WithdrawalTransaction extends BaseTransaction {
+ private BankAccount appliedAccount = null;
+ private boolean isApplied = false;
+ private double shortfallRecord = 0.0;
+
public WithdrawalTransaction(int amount, @NotNull Calendar date) {
super(amount, date);
}
@@ -17,29 +20,73 @@ private boolean checkDepositAmount(int amt) {
}
}
- // Method to reverse the transaction
+ // Question 2: Reversal logic restores the account balance to its original amount
public boolean reverse() {
- return true;
- } // return true if reversal was successful
+ if (isApplied && appliedAccount != null) {
+ double currentBalance = appliedAccount.getBalance();
+ // Restore original amount (current balance + what was successfully withdrawn)
+ double restoredBalance = currentBalance + (getAmount() - shortfallRecord);
+ appliedAccount.setBalance(restoredBalance);
+ isApplied = false; // Reset state
+ System.out.println("Withdrawal transaction reversed successfully.");
+ return true;
+ }
+ System.out.println("Reversal failed: Transaction has not been applied yet.");
+ return false;
+ }
// Method to print a transaction receipt or details
+ @Override
public void printTransactionDetails() {
- System.out.println("Deposit Trasaction: " + this.toString());
+ System.out.println("--- Withdrawal Transaction ---");
+ System.out.println("Transaction ID: " + getTransactionID());
+ System.out.println("Date: " + getDate().getTime());
+ System.out.println("Amount Requested: " + getAmount());
+ if (shortfallRecord > 0) {
+ System.out.println("Shortfall (Not Withdrawn): " + shortfallRecord);
+ }
}
- /*
- Oportunity for assignment: implementing different form of withdrawal
- */
- public void apply(BankAccount ba) {
+ // Question 3: Standard apply using the throws keyword
+ @Override
+ public void apply(BankAccount ba) throws InsufficientFundsException {
double curr_balance = ba.getBalance();
- if (curr_balance > getAmount()) {
+ if (curr_balance >= getAmount()) {
double new_balance = curr_balance - getAmount();
ba.setBalance(new_balance);
+ this.appliedAccount = ba;
+ this.isApplied = true;
+ this.shortfallRecord = 0.0;
+ } else {
+ throw new InsufficientFundsException("Insufficient funds to complete the withdrawal of " + getAmount());
}
}
- /*
- Assignment 1 Q3: Write the Reverse method - a method unique to the WithdrawalTransaction Class
- */
-}
-
+ // Question 3: Overloaded apply handling 0 < balance < withdrawal amount using try...catch...finally
+ public void apply(BankAccount ba, boolean partialWithdrawalAllowed) {
+ try {
+ double curr_balance = ba.getBalance();
+ if (curr_balance < getAmount()) {
+ // Check if balance is greater than 0 for partial withdrawal
+ if (curr_balance > 0) {
+ shortfallRecord = getAmount() - curr_balance;
+ ba.setBalance(0.0); // Withdraw all available balance
+ this.appliedAccount = ba;
+ this.isApplied = true;
+ System.out.println("Partial withdrawal executed. Balance set to 0. Shortfall: " + shortfallRecord);
+ } else {
+ // Trigger exception block manually if balance is 0 or less
+ throw new InsufficientFundsException("Account balance is zero or negative. Cannot withdraw.");
+ }
+ } else {
+ // If funds are completely sufficient, proceed normally via standard apply
+ apply(ba);
+ }
+ } catch (InsufficientFundsException e) {
+ System.out.println("Caught Exception inside overloaded apply: " + e.getMessage());
+ this.isApplied = false;
+ } finally {
+ System.out.println("Transaction processing attempt finished for Transaction ID: " + getTransactionID());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Main.java b/src/Main.java
index 584a048..9d3b022 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -1,4 +1,5 @@
import Lecture1_adt.*; // Import all classes from Lecture1_adt package to be used in this client code
+import Lecture4_interfaces_abstract_classes.*; // Import Lecture 4 assignment files
import java.util.Calendar;
import java.util.GregorianCalendar;
@@ -8,7 +9,7 @@
//TIP To Run code, press or
// click the icon in the gutter.
/*
-* Client Code for accessing the Lecture1_adt.TransactionInterface.java module
+ * Client Code for accessing the Lecture1_adt.TransactionInterface.java module
*/
public class Main {
@@ -56,8 +57,8 @@ public static void testTransaction2() {
System.out.println("Lecture1_adt.TransactionInterface Date: \t "+modified_t.getDate().getTime());
/* Please note that Although we have solved the problem of Transaction1
- * And client code can no longer use the dot (.) operator to directly access the data
- * There is still some exposure especially if we pass an object of a previous Transaction2 to create a new Transaction2 object
+ * And client code can no longer use the dot (.) operator to directly access the data
+ * There is still some exposure especially if we pass an object of a previous Transaction2 to create a new Transaction2 object
*/
}
@@ -143,14 +144,75 @@ public static void testTransaction4() {
// Please Take a look at all the 12 transaction now and compare with the outputs of the Transaction3 class
}
+ /**
+ * Question 4: Client Code to test Assignment 1 functionality
+ */
+ public static void testAssignmentOne() {
+ System.out.println("========== RUNNING ASSIGNMENT 1 TEST CODE ==========");
+
+ // 1. Setup account and common date object
+ BankAccount account = new BankAccount(5000.0);
+ Calendar now = new GregorianCalendar();
+
+ System.out.println("Initial Bank Account Balance: " + account.getBalance());
+
+ // 2. Instantiate Subclass Objects
+ DepositTrasaction deposit = new DepositTrasaction(2000, now);
+ WithdrawalTransaction withdrawal1 = new WithdrawalTransaction(3000, now);
+ WithdrawalTransaction withdrawal2 = new WithdrawalTransaction(6000, now); // Will cause exception
+ WithdrawalTransaction partialWithdrawal = new WithdrawalTransaction(8000, now); // For overloaded test
+
+ // 3. Type casting / Mapping subtype objects to the base type object (Upcasting)
+ BaseTransaction baseDeposit = (BaseTransaction) deposit;
+ BaseTransaction baseWithdrawal1 = (BaseTransaction) withdrawal1;
+ BaseTransaction baseWithdrawal2 = (BaseTransaction) withdrawal2;
+
+ try {
+ // 4. Apply Deposit via Base type mapping
+ System.out.println("\n--- Executing Deposit ---");
+ baseDeposit.apply(account);
+ baseDeposit.printTransactionDetails();
+ System.out.println("Balance after Deposit: " + account.getBalance());
+
+ // 5. Apply valid Withdrawal via Base type mapping
+ System.out.println("\n--- Executing Valid Withdrawal ---");
+ baseWithdrawal1.apply(account);
+ baseWithdrawal1.printTransactionDetails();
+ System.out.println("Balance after Withdrawal 1: " + account.getBalance());
+
+ // 6. Test Reversal on the successful withdrawal
+ System.out.println("\n--- Testing Reversal on Withdrawal 1 ---");
+ withdrawal1.reverse();
+ System.out.println("Balance after Reversal: " + account.getBalance());
+
+ // 7. Apply invalid Withdrawal (Should throw InsufficientFundsException)
+ System.out.println("\n--- Executing Invalid Withdrawal (Expect Exception) ---");
+ baseWithdrawal2.apply(account); // This line will jump to the catch block
+
+ } catch (InsufficientFundsException e) {
+ System.out.println("Successfully caught handled exception: " + e.getMessage());
+ }
- public static void main(String[] args) {
- // This is the client code
- // Uncomment the following lines to test the class which you would like to test
+ // 8. Test Overloaded apply method (Partial withdrawal scenario)
+ System.out.println("\n--- Executing Overloaded Apply (Partial Withdrawal Option) ---");
+ System.out.println("Current Account Balance before partial: " + account.getBalance());
+
+ // Attempting to withdraw 8000 when balance is less than that but greater than 0
+ partialWithdrawal.apply(account, true);
+ partialWithdrawal.printTransactionDetails();
+ System.out.println("Final Account Balance after partial withdrawal loop: " + account.getBalance());
- // testTransaction1()
- // testTransaction2()
- // testTransaction3()
- // testTransaction4()
+ System.out.println("====================================================");
+ }
+
+ public static void main(String[] args) {
+ // Run assignment test execution
+ testAssignmentOne();
+
+ // Uncomment the following lines to run historical lecture tests if needed
+ // testTransaction1();
+ // testTransaction2();
+ // testTransaction3();
+ // testTransaction4();
}
}
\ No newline at end of file