From 4b4ea4970521b128d36c1e4f611e6f6f7969dcf4 Mon Sep 17 00:00:00 2001 From: Rubesh S Date: Sat, 28 Oct 2023 20:05:42 +0800 Subject: [PATCH] Add transaction predicate map and support classes --- .../commons/enums/TransactionProperty.java | 13 +++ src/main/java/unicash/commons/util/Pair.java | 55 +++++++++++ .../predicates/BooleanPredicatePair.java | 33 +++++++ ...ansactionContainsAllKeywordsPredicate.java | 97 +++++++++---------- 4 files changed, 148 insertions(+), 50 deletions(-) create mode 100644 src/main/java/unicash/commons/enums/TransactionProperty.java create mode 100644 src/main/java/unicash/commons/util/Pair.java create mode 100644 src/main/java/unicash/model/transaction/predicates/BooleanPredicatePair.java diff --git a/src/main/java/unicash/commons/enums/TransactionProperty.java b/src/main/java/unicash/commons/enums/TransactionProperty.java new file mode 100644 index 00000000000..96e102ad285 --- /dev/null +++ b/src/main/java/unicash/commons/enums/TransactionProperty.java @@ -0,0 +1,13 @@ +package unicash.commons.enums; + +/** + * An enum of all available transaction properties. + */ +public enum TransactionProperty { + AMOUNT, + CATEGORY, + DATETIME, + LOCATION, + NAME, + TYPE; +} diff --git a/src/main/java/unicash/commons/util/Pair.java b/src/main/java/unicash/commons/util/Pair.java new file mode 100644 index 00000000000..b54df14f5b4 --- /dev/null +++ b/src/main/java/unicash/commons/util/Pair.java @@ -0,0 +1,55 @@ +package unicash.commons.util; + +/** + * A Generic Pair class for utility purposes. + * @param type parameter of the first type of {@code Object} to be contained + * @param type parameter of the second type of {@code Object} to be contained + */ +public class Pair { + private T t; + private U u; + + /** + * Creates the pair object. + * @param t The first object + * @param u The second object + */ + public Pair(T t, U u) { + this.t = t; + this.u = u; + } + + /** + * Returns the first object. + */ + public T getFirst() { + return t; + } + + /** + * Returns the second object + */ + public U getSecond() { + return u; + } + + /** + * Sets the first object. + */ + public void setFirst(T t) { + this.t = t; + } + + /** + * Sets the second object. + */ + public void setSecond() { + this.u = u; + } + + @Override + public String toString() { + return "[" + t + ", " + u + "]"; + } + +} diff --git a/src/main/java/unicash/model/transaction/predicates/BooleanPredicatePair.java b/src/main/java/unicash/model/transaction/predicates/BooleanPredicatePair.java new file mode 100644 index 00000000000..6070a7a1f6c --- /dev/null +++ b/src/main/java/unicash/model/transaction/predicates/BooleanPredicatePair.java @@ -0,0 +1,33 @@ +package unicash.model.transaction.predicates; + +import unicash.commons.util.Pair; +import unicash.model.transaction.Transaction; + +import java.util.function.Predicate; + +/** + * A wrapper class for containing Boolean and TransactionPredicate pairs. + */ +public class BooleanPredicatePair + extends Pair> { + + /** + * Creates the transaction predicate pair object. + * + * @param isActive The boolean indicating the status of the predicate + * @param transactionPredicate The transaction property predicate + */ + public BooleanPredicatePair(Boolean isActive, Predicate transactionPredicate) { + super(isActive, transactionPredicate); + } + + /** + * Creates the transaction predicate pair object with default false value + * + * @param transactionPredicate The transaction property predicate + */ + public BooleanPredicatePair(Predicate transactionPredicate) { + super(false, transactionPredicate); + } + +} diff --git a/src/main/java/unicash/model/transaction/predicates/TransactionContainsAllKeywordsPredicate.java b/src/main/java/unicash/model/transaction/predicates/TransactionContainsAllKeywordsPredicate.java index 81e974c4dc0..028194d7e06 100644 --- a/src/main/java/unicash/model/transaction/predicates/TransactionContainsAllKeywordsPredicate.java +++ b/src/main/java/unicash/model/transaction/predicates/TransactionContainsAllKeywordsPredicate.java @@ -1,14 +1,14 @@ package unicash.model.transaction.predicates; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.function.Predicate; +import unicash.commons.enums.TransactionProperty; import unicash.commons.util.ToStringBuilder; import unicash.model.transaction.Transaction; - - - /** * Tests that any of a {@code Transactions}'s properties matches all the keywords given. * Matching in this context either means a partial match of the keyword with the query, or @@ -24,45 +24,39 @@ public class TransactionContainsAllKeywordsPredicate public static final String EMPTY_STRING = ""; public static final List EMPTY_STRING_LIST = List.of(EMPTY_STRING); - private TransactionAmountContainsValuePredicate amountPredicate; - private boolean amountPredicateExists; - - private TransactionCategoryContainsKeywordsPredicate categoryPredicate; - private TransactionDateTimeContainsValuePredicate dateTimePredicate; - private TransactionLocationContainsKeywordsPredicate locationPredicate; - private TransactionNameContainsKeywordsPredicate namePredicate; - private boolean namePredicateExists; - - private TransactionTypeContainsValuePredicate typePredicate; - private Predicate composedTransactionPredicate; - + public HashMap + predicatePairMap = new HashMap<>(); /** * Creates a composed predicate object. */ public TransactionContainsAllKeywordsPredicate() { - amountPredicate = new TransactionAmountContainsValuePredicate(EMPTY_STRING_LIST); - amountPredicateExists = false; - - categoryPredicate = new TransactionCategoryContainsKeywordsPredicate(EMPTY_STRING_LIST); - dateTimePredicate = new TransactionDateTimeContainsValuePredicate(EMPTY_STRING_LIST); - locationPredicate = new TransactionLocationContainsKeywordsPredicate(EMPTY_STRING_LIST); - - namePredicate = new TransactionNameContainsKeywordsPredicate(EMPTY_STRING_LIST); - namePredicateExists = false; - - typePredicate = new TransactionTypeContainsValuePredicate(EMPTY_STRING_LIST); - composedTransactionPredicate = amountPredicate - .and(categoryPredicate) - .and(dateTimePredicate) - .and(locationPredicate) - .and(namePredicate) - .and(typePredicate); + + TransactionAmountContainsValuePredicate amountPredicate = + new TransactionAmountContainsValuePredicate(EMPTY_STRING_LIST); + TransactionCategoryContainsKeywordsPredicate categoryPredicate = + new TransactionCategoryContainsKeywordsPredicate(EMPTY_STRING_LIST); + TransactionDateTimeContainsValuePredicate dateTimePredicate = + new TransactionDateTimeContainsValuePredicate(EMPTY_STRING_LIST); + TransactionLocationContainsKeywordsPredicate locationPredicate = + new TransactionLocationContainsKeywordsPredicate(EMPTY_STRING_LIST); + TransactionNameContainsKeywordsPredicate namePredicate = + new TransactionNameContainsKeywordsPredicate(EMPTY_STRING_LIST); + TransactionTypeContainsValuePredicate typePredicate = + new TransactionTypeContainsValuePredicate(EMPTY_STRING_LIST); + + predicatePairMap.put(TransactionProperty.AMOUNT, new BooleanPredicatePair(amountPredicate)); + predicatePairMap.put(TransactionProperty.CATEGORY, new BooleanPredicatePair(categoryPredicate)); + predicatePairMap.put(TransactionProperty.DATETIME, new BooleanPredicatePair(dateTimePredicate)); + predicatePairMap.put(TransactionProperty.LOCATION, new BooleanPredicatePair(locationPredicate)); + predicatePairMap.put(TransactionProperty.NAME, new BooleanPredicatePair(namePredicate)); + predicatePairMap.put(TransactionProperty.TYPE, new BooleanPredicatePair(typePredicate)); + } @Override public boolean test(Transaction transaction) { - Predicate composedPredicate = composeAllPredicates(); + Predicate composedPredicate = composeAllActivePredicates(); return composedPredicate.test(transaction); } @@ -72,28 +66,35 @@ public boolean test(Transaction transaction) { * * @return a composed predicate */ - public Predicate composeAllPredicates() { + public Predicate composeAllActivePredicates() { Predicate composedPredicate = unused -> true; - if (amountPredicateExists) { - composedPredicate = composedPredicate.and(amountPredicate); - } + for (TransactionProperty property : predicatePairMap.keySet()) { + Boolean predicateState = predicatePairMap.get(property).getFirst(); + Predicate predicate = predicatePairMap.get(property).getSecond(); - if (namePredicateExists) { - composedPredicate = composedPredicate.and(namePredicate); + if (predicateState) { + composedPredicate = composedPredicate.and(predicate); + } } return composedPredicate; } public void setAmount(String amount) { - amountPredicate = new TransactionAmountContainsValuePredicate(List.of(amount)); - amountPredicateExists = true; + BooleanPredicatePair predicatePair = new BooleanPredicatePair(true, + new TransactionAmountContainsValuePredicate( + Collections.singletonList(amount))); + + predicatePairMap.put(TransactionProperty.AMOUNT, predicatePair); } public void setName(String name) { - namePredicate = new TransactionNameContainsKeywordsPredicate(List.of(name)); - namePredicateExists = true; + BooleanPredicatePair predicatePair = new BooleanPredicatePair(true, + new TransactionNameContainsKeywordsPredicate( + Collections.singletonList(name))); + + predicatePairMap.put(TransactionProperty.NAME, predicatePair); } @@ -111,19 +112,15 @@ public boolean equals(Object other) { TransactionContainsAllKeywordsPredicate otherContainsKeywordsPredicate = (TransactionContainsAllKeywordsPredicate) other; - return amountPredicate.equals(otherContainsKeywordsPredicate.amountPredicate) - && namePredicate.equals(otherContainsKeywordsPredicate.namePredicate) - && composedTransactionPredicate.equals(otherContainsKeywordsPredicate - .composedTransactionPredicate); + return predicatePairMap.equals( + otherContainsKeywordsPredicate.predicatePairMap); } @Override public String toString() { return new ToStringBuilder(this) - .add("composedTransactionPredicate", composedTransactionPredicate) - .add("amountPredicate", amountPredicate) - .add("namePredicate", namePredicate) + .add("predicatePairMap", predicatePairMap) .toString(); } }