package za.co.javajoe.utilities;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import za.co.javajoe.confiurations.AmountConfigs;
import za.co.javajoe.dao.AccountDao;
import za.co.javajoe.dao.CustomerDao;
import za.co.javajoe.domain.Account;
import za.co.javajoe.domain.AgentDetails;
import za.co.javajoe.domain.Customer;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import com.google.common.collect.Lists;
import com.google.common.base.Functions;
/**
* AUTHOR: Thabo Matjuda
* DATE: 29 June 2014
* DESCRIPTION: This class will be used for various/ common util.
* Made it an abstract class for the sake of fun.
* Also trying to avoid having to instatiate a class whenever I need quick utils workto be done.
* Feel free to add any methods that you keep on re-coding more than twice in you business logic.
* There are more reasons to use Abbstract classes check below...
*
* BASIC BACKGROUND:
* Java Abstract classes are used to declare common characteristics of subclasses.
* An abstract class cannot be instantiated.
* It can only be used as a superclass for other classes that extend the abstract class.
* Abstract classes are declared with the abstract keyword. Abstract classes are used to provide a template or design for concrete subclasses down the inheritance tree.
*/
public final class JoeUtil {
/**
* So Java has it's own util to convert an Array to List.
* For the fun if it, this is how I would have done it if I were to do it myself.
* Although this way is limited to Sting objects.
* It entirely depends on which object type you are busy with.
* So Here's a quick demo for String version.
* You could go even further by playing with the Object Type. - T.L. Matjuda
*
*/
private static CustomerDao customerDao = new CustomerDao();
private static AccountDao accountDao = new AccountDao();
public static List<String> convertStringArrayToList(String[] stringArrayToConvert) {
List<String> peopleNamesList = new ArrayList<String>();
//Just loop through the arrays and unpack them into the List, that simple.
for ( String stringNames : stringArrayToConvert) {
peopleNamesList.add( stringNames);
}
return peopleNamesList;
}
/**
* Creates & returns a list of customers
* @return
*/
public static List<Customer> getCustomers() {
/* Getting all Customers from the CustomerDao as if *findAll Customers from DB* - @Tlou
@mack
changed the method made the customerDao object global so that every class can hav access to the
list we dnt hav to create new list object in every method */
return customerDao.getCustomerList();
}
/**
* Creates and returns a list of accounts
* @return
*/
public static List<Account> getAccounts() {
// Getting all Accounts from the AccountsDao as if *findAll Accounts from DB* - @Tlou
return accountDao.getAccountList();
}
/**
* returns a specific customers from the customerList
* @return
*/
public Customer getCustomerById(String customerId){
for(Customer customerTemp:customerDao.getCustomerList()){
if(customerTemp.getId()==customerId){
System.out.println("====Customer is found====");
return customerTemp;
}
}
System.out.println("====Customer is found not found ====");
return null;
}
/**
* this method gets a list of accounts linked to the same accountNum and adds
* them to a list
* @return
*/
public List<Account> getAccountbyAccountId(String accountId){
List<Account> AccountListTemp = new ArrayList<Account>();
for(Account accountTemp:accountDao.getAccountList()) {
if(accountTemp.getAccountID()==accountId){
AccountListTemp.add(accountTemp);
}
}
return AccountListTemp;
}
public List<Customer> getCutomerbyAccounttId(String accountId){
List<Customer> CustomerListTemp = new ArrayList<Customer>();
for(Customer customerTemp:customerDao.getCustomerList()) {
if(customerTemp.getAccountID()==accountId){
CustomerListTemp.add(customerTemp);
}
}
return CustomerListTemp;
}
public List<?> getLinkedAccounts(){
return null;
}
/**
* This method checks if a BigDecimal Amount is Greater thatn Zero.
* If so then it will return true.
* @param amountToValidate
* @return
*/
public static boolean amountIsGreaterThanZero ( BigDecimal amountToValidate) {
//Definitely not greater than zero if nulll or equal to zero
if ( amountToValidate == null ||
amountToValidate.compareTo( BigDecimal.ZERO) == 0) {
return false;
}
//Returns true if the amount is Greater Than ZERO
if ( amountToValidate.compareTo( BigDecimal.ZERO) > 0) {
return true;
}
return false;
}
/**
* Basically gives you the accountNumber back, based on the given accountPK
* @param accounts Collection of the existing accounts in the system.
* @param accountPK The key that you want the accountNumber for.
* @return
*/
public static String getAccountNumberFromID( List<Account> accounts, String accountPK) {
Validate.notNull( accounts, "No List Collection (List) To Check From");
Validate.notNull( accountPK, "No Account ID (PK) Supplied");
for ( Account accountItem : accounts) {
if ( accountItem.getAccountID().equals( accountPK)) {
return accountItem.getAccountNumber();
}
}
return "";
}
/**
* Will return true if the amount is not less than minimum amount AND
* if the amount is not more than the maximum amount.
* @param transactionAmount amount that the client is using for transaction.
* @return boolean
*/
public static boolean amountIsWithinRange( BigDecimal transactionAmount) {
AmountConfigs amountConfigs = ConfigUtil.getAmountConfigs();
Validate.notNull( amountConfigs, "Error, Configurations are NULL");
Validate.notNull( amountConfigs.getMinimumAmount(), "Error, Config (Min Amount) is NULL");
Validate.notNull( amountConfigs.getMaximumAmount(), "Error, Config (Max Amount) is NULL");
if ( !amountMoreThanMinimum( transactionAmount, amountConfigs.getMinimumAmount()) ||
!amountLessThanMaximum( transactionAmount, amountConfigs.getMaximumAmount())) {
return false;
}
return true;
}
/**
* Checks if the transactionAmount is Greater than minimumAmount
* Returns true if the transactionAmount is bigger tham the minimumAmount
* @param transactionAmount
* @param minimumAmount
* @return
*/
public static boolean amountMoreThanMinimum( BigDecimal transactionAmount, BigDecimal minimumAmount) {
//When the amount is biggger than Min
if ( transactionAmount.compareTo( minimumAmount) == 1 ||
transactionAmount.compareTo( minimumAmount) == 0) {
return true;
}
return false;
}
/**
* Checks if the transactionAmount is Less than maximumAmount
* Returns true if the transactionAmount is Less than maximumAmount
* @param transactionAmount
* @param maximumAmount
* @return
*/
public static boolean amountLessThanMaximum( BigDecimal transactionAmount, BigDecimal maximumAmount) {
//When the amount is less than the maximum
if ( transactionAmount.compareTo( maximumAmount) == -1 ||
transactionAmount.compareTo( maximumAmount) == 0) {
return true;
}
return false;
}
/**
*
* @param accountPK
* @return
*/
public static String getAccountNumberFromID( String accountPK) {
Validate.notNull( getAccounts(), "No List Collection (List) To Check From");
Validate.notNull( accountPK, "No Account ID (PK) Supplied");
for ( Account accountItem : getAccounts()) {
if ( accountItem.getAccountID().equals( accountPK)) {
return accountItem.getAccountNumber();
}
}
return "";
}
/**
* this method takes the worksheet as a parameter and Maps the Row to AgentDetails`s Object
* @param worksheet
* @return
*/
public static List<AgentDetails> mapExacelToObject(HSSFSheet worksheet) {
List<AgentDetails> agentDetailList = new ArrayList<AgentDetails>();
List<String> data = new ArrayList();
//Iterates through the workSheet row
Iterator<Row> rowIterator = worksheet.iterator();
//this while makes sure that all the Rows have been visited
while (rowIterator.hasNext()) {
//attributes used to Map to AgentDetails
String bankAccountNo = "";
String transactionDescription = "";
String userReferenceNo = "";
String transactionAmount = "";
String businessDate = "";
String agentID = "";
String agentIdentification = "";
String agentName = "";
String agentAccountNumber = "";
Row row = rowIterator.next();
if(row.getRowNum()==0 || row.getRowNum()==0){
continue; //just skip the rows if row number is 0 or 1
}
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
HSSFCell cell = (HSSFCell) cellIterator.next();
data.add(cell.toString());
Validate.notNull(data);
if (bankAccountNo.equalsIgnoreCase("")) {
bankAccountNo = cell.toString().trim();
} else if (transactionDescription.equalsIgnoreCase("")) {
transactionDescription = cell.toString().trim();
} else if (userReferenceNo.equalsIgnoreCase("")) {
userReferenceNo = cell.toString().trim();
} else if (transactionAmount.equalsIgnoreCase("")) {
transactionAmount = cell.toString().trim();
} else if (transactionAmount.equalsIgnoreCase("")) {
transactionAmount = cell.toString().trim();
} else if (businessDate.equalsIgnoreCase("")) {
businessDate = cell.toString().trim();
} else if (agentID.equalsIgnoreCase("")) {
/* int i = (int) cell.getNumericCellValue();
agentID = String.valueOf(i);*/
agentID = cell.toString().trim();
} else if (agentIdentification.equalsIgnoreCase("")) {
/* int i = (int) cell.getNumericCellValue();
agentIdentification = String.valueOf(i);*/
agentIdentification = cell.toString().trim();
} else if (agentName.equalsIgnoreCase("")) {
agentName = cell.toString().trim();
} else if (agentAccountNumber.equalsIgnoreCase("")) {
/* long i = (long) cell.getNumericCellValue();
agentAccountNumber = String.valueOf(i);*/
agentAccountNumber = cell.toString().trim();
}
}
//Map the colums to the AgentDetails using a constractor to initialize the object of AgentDetails
AgentDetails c = new AgentDetails( bankAccountNo,
transactionDescription,
userReferenceNo,
transactionAmount,
businessDate,
agentID,
agentIdentification,
agentName,
agentAccountNumber);
agentDetailList.add(c);
}
//Print the AgentDetails
for(AgentDetails item:agentDetailList){
System.out.println("===>"+item.getBankAccountNo() +"--"
+item.getTransactionDescription() +"--"
+item.getUserReferenceNo()+"--"
+item.getTransactionAmount()+"--"
+item.getBusinessDate()+"--"
+item.getAgentID()+"--"
+item.getAgentIdentification()+"--"
+item.getAgentName()+"--"
+ item.getAgentAccountNumber());
}
return agentDetailList;
}
/**
* This method calculates how many times a letter appears inside a word.
* Then prints out the result.
* @param wordToCheck
*/
public static void calculateWordLetters( String wordToCheck) {
String validationErrorMessage = "The String Literal To Check Is NULL / EMPTY";
//Performing some validations here
Validate.notNull( wordToCheck, validationErrorMessage + " (NULL)");
if ( StringUtils.isEmpty( wordToCheck) || StringUtils.isBlank( wordToCheck)) {
throw new RuntimeException( validationErrorMessage + " (BLANK OR EMPTY)");
}
//Converting the word to lower case to avoid some confusion
wordToCheck = wordToCheck.toLowerCase();
//Quickly unpacking the word into and array to isolate the letters
char[] tempCharArray = wordToCheck.toCharArray();
Map<String, Long> charMap = new HashMap<String, Long>();
/**
* Looping through the charater array.
* This array just has the word unpacked character by character into and array.
*/
for ( char c : tempCharArray) {
/**
* When the map already has something inside
*/
if ( charMap.size() > 0) {
/**
* If the map already has the charater then just increment it's appearance total.
* The following code are the steps you need to take.
*/
if ( charMap.containsKey( String.valueOf( c))) {
//Get the value
Long total = charMap.get( String.valueOf( c));
//Increment it's appearance
total++;
//Push it pack where it was but, with the new value
charMap.put( String.valueOf( c), total);
//We are done, so move to the next character if there are more
continue;
}
}
//Put a new non-existing letter into the map
charMap.put( String.valueOf( c), 1L);
}
//Printout the user's word
System.out.print("\nYOU HAVE SENT THE WORD: "+ wordToCheck + "\n");
//Loop through the Map and show the user what the result it
for ( Map.Entry<String, Long> mapRow : charMap.entrySet()) {
System.out.println("THE LETTER: (" + mapRow.getKey()
+ ") APPEARS "+ mapRow.getValue()
+ " TIME(S) IN YOUR STRING LITERAL, SIR / MA'AM");
}
}
}