oracle.retail.stores.pos.ado.utility.Utility.java Source code

Java tutorial

Introduction

Here is the source code for oracle.retail.stores.pos.ado.utility.Utility.java

Source

/* ===========================================================================
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. 
 * ===========================================================================
 * $Header: rgbustores/applications/pos/src/oracle/retail/stores/pos/ado/utility/Utility.java /rgbustores_13.4x_generic_branch/2 2011/07/20 04:33:40 rrkohli Exp $
 * ===========================================================================
 * NOTES
 * <other useful comments, qualifications, etc.>
 *
 * MODIFIED    (MM/DD/YY)
 *    rrkohli   07/19/11 - encryption CR
 *    blarsen   06/22/11 - Added isOvertenderAllowed() method.
 *    blarsen   06/22/11 - Added another (overloaded) isStringListed method.
 *    mkutiana  02/22/11 - Added logic to get the correct password policy and
 *                         if fingerprints for login are allowed
 *    mchellap  07/30/10 - Added validation for customer id expiration date
 *    cgreene   05/26/10 - convert to oracle packaging
 *    cgreene   05/11/10 - convert Base64 from axis
 *    cgreene   05/11/10 - updating deprecated names
 *    cgreene   04/26/10 - XbranchMerge cgreene_tech43 from
 *                         st_rgbustores_techissueseatel_generic_branch
 *    cgreene   04/02/10 - remove deprecated LocaleContantsIfc and currencies
 *    abondala  01/03/10 - update header date
 *    abondala  11/06/08 - updated files related to reason codes
 *
 * ===========================================================================
 * $Log:
 *  5    360Commerce 1.4         3/29/2007 3:59:50 PM   Michael Boyd    CR
 *       26172 - v8x merge to trunk
 *
 *
 *       5    .v8x      1.3.1.0     3/11/2007 4:51:18 PM   Brett J. Larsen CR
 *       4530 -
 *       adding support for retrieval of devault code list value - several
 *       site/model/beans do not work direclty with CodeList
 *  4    360Commerce 1.3         7/28/2006 5:36:00 PM   Brett J. Larsen CR
 *       4530: default reason code fix
 *       v7x->360Commerce merge
 *  3    360Commerce 1.2         3/31/2005 4:30:41 PM   Robert Pearse
 *  2    360Commerce 1.1         3/10/2005 10:26:38 AM  Robert Pearse
 *  1    360Commerce 1.0         2/11/2005 12:15:27 PM  Robert Pearse
 * $
 *
 *  4    .v7x      1.2.1.0     6/23/2006 4:43:05 AM   Dinesh Gautam   CR 4530:
 *       Fixed for reason code
 *
 * Revision 1.7  2004/09/15 16:34:22  kmcbride
 * @scr 5881: Deprecating parameter retrieval logic in cargo classes and logging parameter exceptions
 *
 * Revision 1.6  2004/07/14 18:47:09  epd
 * @scr 5955 Addressed issues with Utility class by making constructor protected and changing all usages to use factory method rather than direct instantiation
 *
 * Revision 1.5  2004/07/12 21:30:34  bwf
 * @scr 6125 Made available expiration validation of debit before pin.
 *
 * Revision 1.4  2004/05/17 03:48:01  blj
 * @scr 4974 - resolution for this scr
 *
 * Revision 1.3  2004/02/12 16:47:58  mcs
 * Forcing head revision
 *
 * Revision 1.2  2004/02/11 21:12:55  rhafernik
 * @scr 0 Log4J conversion and code cleanup
 * Revision 1.1.1.1 2004/02/11 01:04:11 cschellenger
 * updating to pvcs 360store-current
 *
 *
 *
 * Rev 1.4 Feb 05 2004 13:24:20 rhafernik log4j conversion
 *
 * Rev 1.3 Jan 22 2004 14:05:40 khassen Resolution for scr3705: added empty
 * string entry in getIDTypes method. Resolution for 3705: Default selection
 * for ID Type is the previous selection; instead of blank selection
 *
 * Rev 1.2 Dec 17 2003 14:48:46 epd Refactorings to accommodate Unit testing
 *
 * Rev 1.1 Nov 07 2003 13:24:06 bwf Added validate license. Resolution for
 * 3429: Check/ECheck Tender
 *
 * Rev 1.0 Nov 04 2003 11:15:08 epd Initial revision.
 *
 * Rev 1.1 Oct 31 2003 16:46:40 epd added utility method to get ID types
 *
 * Rev 1.0 Oct 17 2003 12:39:08 epd Initial revision.
 * ===========================================================================
 */
package oracle.retail.stores.pos.ado.utility;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Vector;

import oracle.retail.stores.keystoreencryption.EncryptionServiceException;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import oracle.retail.stores.common.parameter.ParameterConstantsIfc;
import oracle.retail.stores.domain.utility.LocaleConstantsIfc;
import oracle.retail.stores.pos.ado.ADOException;
import oracle.retail.stores.pos.ado.context.ADOContextIfc;
import oracle.retail.stores.pos.ado.context.ContextFactory;
import oracle.retail.stores.pos.ado.tender.TenderErrorCodeEnum;
import oracle.retail.stores.pos.ado.tender.TenderException;
import oracle.retail.stores.pos.ado.tender.TenderTypeEnum;
import oracle.retail.stores.pos.ado.utility.tdo.FingerprintPasswordPolicyTDO;
import oracle.retail.stores.pos.ado.utility.tdo.PasswordPolicyTDO;
import oracle.retail.stores.pos.ado.utility.tdo.PasswordPolicyTDOIfc;
import oracle.retail.stores.domain.DomainGateway;
import oracle.retail.stores.domain.manager.ifc.ValidationManagerIfc;
import oracle.retail.stores.domain.utility.CodeConstantsIfc;
import oracle.retail.stores.domain.utility.CodeListIfc;
import oracle.retail.stores.domain.utility.EYSDate;
import oracle.retail.stores.foundation.manager.ifc.KeyStoreEncryptionManagerIfc;
import oracle.retail.stores.foundation.manager.ifc.ParameterManagerIfc;
import oracle.retail.stores.foundation.manager.parameter.ParameterException;
import oracle.retail.stores.foundation.tour.conduit.Dispatcher;
import oracle.retail.stores.foundation.tour.gate.Gateway;
import oracle.retail.stores.foundation.utility.LocaleMap;
import oracle.retail.stores.pos.manager.ifc.UtilityManagerIfc;
import oracle.retail.stores.pos.tdo.TDOFactory;

/**
 * Container for ad-hoc utility methods to be used at ADO layer
 *
 */
public class Utility implements UtilityIfc {
    /** Logger */
    protected static Logger logger = Logger.getLogger(oracle.retail.stores.pos.ado.utility.Utility.class);

    /** protected to enforce Singleton */
    protected Utility() {
    }

    protected static UtilityIfc instance = null;

    /**
     * Factory method that will attempt to return an instance of this class or
     * another implementation as specified by a property file
     *
     * @return
     */
    public static UtilityIfc createInstance() throws ADOException {
        if (instance != null) {
            return instance;
        }

        final String APP_PROP_GROUP = "application";
        final String UTILITY_KEY = "ado.utility";
        final String DEFAULT = Utility.class.getName();

        try {
            String className = Gateway.getProperty(APP_PROP_GROUP, UTILITY_KEY, DEFAULT);
            if (className.length() == 0) {
                throw new ADOException("Failed to find factory class for " + UTILITY_KEY);
            }
            Class utilityClass = Class.forName(className);
            instance = (UtilityIfc) utilityClass.newInstance();
            return instance;
        } catch (ADOException e) {
            throw e;
        } catch (ClassNotFoundException e) {
            throw new ADOException("Factory Class not found for " + UTILITY_KEY, e);
        } catch (InstantiationException e) {
            throw new ADOException("Failed to Instantiate factory for " + UTILITY_KEY, e);
        } catch (IllegalAccessException e) {
            throw new ADOException("IllegalAccessException creating factory for " + UTILITY_KEY, e);
        } catch (NullPointerException e) {
            throw new ADOException("Failed to find class for " + UTILITY_KEY, e);
        } catch (Throwable eth) {
            throw new ADOException("Failed to create factory for " + UTILITY_KEY, eth);
        }

    }

    /*
     * Returns an instance of the oracle.retail.stores.pos.ado.utility.UtilityIfc class
     * @Return UtilityIfc
     */
    public static UtilityIfc getUtil() {
        UtilityIfc util;
        try {
            util = Utility.createInstance();
        } catch (ADOException e) {
            String message = "Configuration problem: could not instantiate UtilityIfc instance";
            logger.error(message, e);
            throw new RuntimeException(message, e);
        }
        return util;
    }

    /**
     * Retrieves a parameter value from the parameter subsystem
     *
     * @param parameterName
     *            The parameter to retrieve
     * @param defaultValue
     *            A default in case the parameter cannot be read
     * @return The retrieved parameter value
     */
    public synchronized String getParameterValue(String parameterName, String defaultValue) {
        // get context
        ADOContextIfc context = getContext();
        // get parameter manager
        ParameterManagerIfc pm = (ParameterManagerIfc) context.getManager(ParameterManagerIfc.TYPE);
        String result = defaultValue;
        try {
            result = pm.getStringValue(parameterName);
        } catch (ParameterException e) {
            // Log the exception, this means we will return the
            // default value, so there should be no reason to
            // re-throw the exception
            //
            logger.warn(e);
        }
        return result;
    }

    /**
     * Retrieves a list of values given a parameter name.
     *
     * @param paramName
     *            The parameter to retrieve.
     * @return an array of values for the given parameter.
     */
    public synchronized String[] getParameterValueList(String paramName) {
        String[] result = new String[0]; // so as not to return a null;

        // get context
        ADOContextIfc context = ContextFactory.getInstance().getContext();
        // get parameter manager
        ParameterManagerIfc pm = (ParameterManagerIfc) context.getManager(ParameterManagerIfc.TYPE);
        try {
            // convert serializable[] to string[]
            Serializable[] values = pm.getParameterValues(paramName);
            result = new String[values.length];
            for (int i = 0; i < values.length; i++) {
                result[i] = (String) values[i];
            }
        } catch (ParameterException e) {
            logger.error(e);
        }

        return result;
    }

    /**
     * Returns true if the specified string is found in the list, false
     * otherwise
     * <P>
     *
     * @return boolean if string exists in list
     */
    public synchronized boolean isStringListed(String str, Object[] list) {
        boolean found = false;
        if (list != null) {
            for (int i = 0; i < list.length; i++) {
                if (str.equals(list[i])) {
                    found = true;
                    break;
                }
            }
        }
        return found;
    }

    /**
     * Gets the ID types from the config file
     *
     * @return Vector of ID types retrieved from the config file
     * @deprecated as of 13.1 Use UtilityManager.getReasonCodes
     */
    public synchronized Vector getIDTypes() {
        ADOContextIfc context = getContext();
        UtilityManagerIfc utility = (UtilityManagerIfc) context.getManager(UtilityManagerIfc.TYPE);
        String storeID = Gateway.getProperty("application", "StoreID", "");
        CodeListIfc list = utility.getReasonCodes(storeID, CodeConstantsIfc.CODE_LIST_CHECK_ID_TYPES);
        Locale lcl = LocaleMap.getLocale(LocaleConstantsIfc.USER_INTERFACE);
        Vector result = list.getTextEntries(lcl);

        return (result);
    }

    /**
     * Gets the mail bank check ID types from the config file
     *
     * @return Vector of ID types retrieved from the config file
     * @deprecated as of 13.1 Use {@link #UtilityManager.getReasonCodes}
     */
    public synchronized Vector getIDTypes(String codeConstant) {
        ADOContextIfc context = getContext();
        UtilityManagerIfc utility = (UtilityManagerIfc) context.getManager(UtilityManagerIfc.TYPE);
        String storeID = Gateway.getProperty("application", "StoreID", "");
        CodeListIfc list = utility.getReasonCodes(storeID, codeConstant);
        Locale lcl = LocaleMap.getLocale(LocaleConstantsIfc.USER_INTERFACE);
        Vector result = list.getTextEntries(lcl);

        return (result);
    }

    /**
     * Gets the default mail bank check ID value from the config file
     *
     * @return Vector of ID types retrieved from the config file
     * @deprecated as of 13.1 Use {@link #UtilityManager.getReasonCodes}
     **/
    public synchronized String getDefaultIDType(String codeConstant) {
        ADOContextIfc context = getContext();
        UtilityManagerIfc utility = (UtilityManagerIfc) context.getManager(UtilityManagerIfc.TYPE);
        String storeID = Gateway.getProperty("application", "StoreID", "");
        CodeListIfc list = utility.getReasonCodes(storeID, codeConstant);
        Locale lcl = LocaleMap.getLocale(LocaleConstantsIfc.USER_INTERFACE);
        return list.getDefaultOrEmptyString(lcl);
    }

    protected synchronized ADOContextIfc getContext() {
        return ContextFactory.getInstance().getContext();
    }

    /**
     * This validates the drivers license.
     *
     * @param state
     * @param license
     * @param country
     * @throws TenderException
     */
    public synchronized void validateDriversLicense(byte[] license, String state, String country)
            throws TenderException {
        ValidationManagerIfc validationManager = (ValidationManagerIfc) Dispatcher.getDispatcher()
                .getManager(ValidationManagerIfc.DRIVERS_LICENECE_TYPE);

        String maskName = country + ValidationManagerIfc.DL_MASK_NAME_POSTFIX;
        if (!validationManager.validateString(state, license, maskName)) {
            throw new TenderException("Invalid Drivers License Format", TenderErrorCodeEnum.INVALID_LICENSE);
        }
    }

    /**
     * Takes an expiration date as entered from the UI and converts it into an
     * EYS date.
     *
     * @param format
     *            A date format describing the formatting of dateStr
     * @param dateStr
     *            a String to convert
     * @return an EYSDate representative of the dateStr string
     */
    public synchronized EYSDate parseExpirationDate(String format, String dateStr) throws TenderException {
        // check for null
        if (dateStr == null) {
            throw new TenderException("Expiration Date is null", TenderErrorCodeEnum.INVALID_EXPIRATION_DATE);
        }
        Locale locale = LocaleMap.getLocale(LocaleConstantsIfc.DEFAULT_LOCALE);
        DateFormat dateFormat = new SimpleDateFormat(format, locale);
        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            throw new TenderException("Invalid expiration date format", TenderErrorCodeEnum.INVALID_EXPIRATION_DATE,
                    e);
        }
        EYSDate eysDate = DomainGateway.getFactory().getEYSDateInstance();
        eysDate.initialize(date);
        return eysDate;
    }

    //----------------------------------------------------------------------
    /**
    This method validates the expiration date.
    @param expirationDate
    @throws TenderException if not a valid expiration date
    **/
    //----------------------------------------------------------------------
    public synchronized void validateExpirationDate(String expDate) throws TenderException {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        // get today's date and from that get the current
        // Month and Year.
        Date today = new Date();
        gc.setTime(today);
        int thisMonth = gc.get(Calendar.MONTH);
        int thisYear = gc.get(Calendar.YEAR);
        gc.clear();
        EYSDate expirationDate = parseEncryptedExpirationDate(expDate);
        // reset the calendar with this tend;er's Exp. Date
        Calendar c = expirationDate.calendarValue();
        gc.setTime(c.getTime());

        // if expiration date is before today and
        // the month and year both do not match the
        // current month and year, the card must be expired.
        EYSDate todayEYS = new EYSDate(today);
        if (expirationDate.before(todayEYS)
                && !((thisMonth == gc.get(Calendar.MONTH)) && (thisYear == gc.get(Calendar.YEAR)))) {
            throw new TenderException("Expired", TenderErrorCodeEnum.EXPIRED);
        }
        // set the object to nul
        expirationDate = null;
    }

    /**
     * Takes an swiped encrypted expiration date and converts it into an EYS date
     *
     * @param format
     *            A date format describing the formatting of expirationDateStr
     * @param expirationDateStr
     *            an encrypted String to convert
     * @return an EYSDate representative of the expirationDate string
     */
    private EYSDate parseEncryptedExpirationDate(String expirationDateStr) throws TenderException {
        String format = EYSDate.CARD_FORMAT_MMYYYY;
        // check for null
        if (expirationDateStr == null) {
            throw new TenderException("Expiration Date is null", TenderErrorCodeEnum.INVALID_EXPIRATION_DATE);
        }
        // decrypt the expiration date
        KeyStoreEncryptionManagerIfc encryptionManager = (KeyStoreEncryptionManagerIfc) Gateway.getDispatcher()
                .getManager(KeyStoreEncryptionManagerIfc.TYPE);
        String decryptedExpDate = "";
        try {
            decryptedExpDate = new String(
                    encryptionManager.decrypt(Base64.decodeBase64(expirationDateStr.getBytes())));
        } catch (EncryptionServiceException ese) {
            logger.warn("Could not decrypt date", ese);
        }
        // determine the date format
        if (decryptedExpDate.length() == 4) {
            format = EYSDate.FORMAT_YYMM;
        }

        if (decryptedExpDate.length() == 6) {
            decryptedExpDate = decryptedExpDate.substring(0, 2) + "/" + decryptedExpDate.substring(2, 6);
        }

        Locale locale = LocaleMap.getLocale(LocaleConstantsIfc.DEFAULT_LOCALE);
        DateFormat dateFormat = new SimpleDateFormat(format, locale);
        Date date = null;
        try {
            date = dateFormat.parse(decryptedExpDate.toString());
        } catch (ParseException e) {
            throw new TenderException("Invalid expiration date format", TenderErrorCodeEnum.INVALID_EXPIRATION_DATE,
                    e);
        }
        EYSDate eysDate = DomainGateway.getFactory().getEYSDateInstance();
        eysDate.initialize(date);
        return eysDate;
    }

    /**
     *   This method checks if the entered expiry date of ID is valid. Returns false
     *   if entered expiry date is before the current date. True otherwise.
     *   @param expirationDate
     *   @throws TenderException if not a valid expiration date
     */
    public boolean isValidExpirationDate(String expirationDate) throws TenderException {
        boolean result = true;
        Date today = new Date();
        EYSDate todayEYS = new EYSDate(today);
        String format = EYSDate.ID_EXPIRATION_DATE_FORMAT;
        Locale locale = LocaleMap.getLocale(LocaleConstantsIfc.DEFAULT_LOCALE);
        DateFormat dateFormat = new SimpleDateFormat(format, locale);
        Date date = null;
        EYSDate dateEYS = null;
        try {
            date = dateFormat.parse(expirationDate);
            dateEYS = new EYSDate(date);
        } catch (ParseException e) {
            throw new TenderException("Invalid expiration date format", TenderErrorCodeEnum.INVALID_EXPIRATION_DATE,
                    e);
        }
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(today);
        int thisMonth = gc.get(Calendar.MONTH);
        int thisYear = gc.get(Calendar.YEAR);
        gc.clear();
        Calendar c = dateEYS.calendarValue();
        gc.setTime(c.getTime());
        if (dateEYS.before(todayEYS)
                && !((thisMonth == gc.get(Calendar.MONTH)) && (thisYear == gc.get(Calendar.YEAR)))) {
            result = false;
        }
        return result;
    }

    /*
     * @see oracle.retail.stores.pos.ado.utility.UtilityIfc#getPasswordPolicyTDO()
     */
    public PasswordPolicyTDOIfc getPasswordPolicyTDO() {
        //Defaulting to manual enter password style password policy
        String passwordPolicyType = PasswordPolicyTDO.PASSWORD_POLICY_TDO_BEAN_KEY;

        if (isFingerprintAllowed()) {
            passwordPolicyType = FingerprintPasswordPolicyTDO.FINGERPRINT_PASSWORD_POLICY_TDO_BEAN_KEY;
        }
        PasswordPolicyTDOIfc tdo = (PasswordPolicyTDOIfc) TDOFactory.createBean(passwordPolicyType);
        return tdo;
    }

    /*
    * @see oracle.retail.stores.pos.ado.utility.UtilityIfc#isFingerprintAllowed()
    */
    public boolean isFingerprintAllowed() {
        String fingerprintOption = getParameterValue(ParameterConstantsIfc.OPERATORID_FingerprintLoginOptions,
                ParameterConstantsIfc.OPERATORID_FingerprintLoginOptions_NO_FINGERPRINT);
        return !ParameterConstantsIfc.OPERATORID_FingerprintLoginOptions_NO_FINGERPRINT.equals(fingerprintOption);
    }

    /*
     * @see oracle.retail.stores.pos.ado.utility.UtilityIfc#isStringListed(String, String)
     */
    public boolean isStringListed(String parameterValue, String parameterName) {
        String[] parameterList = getParameterValueList(parameterName);
        return isStringListed(parameterValue, parameterList);
    }

    /*
    * @see oracle.retail.stores.pos.ado.utility.UtilityIfc#isOvertenderAllowed(String)
    */
    public boolean isOvertenderAllowed(String tenderType) {

        // In 13.4 the customer selects credit, debit or gift card after the tender options are selected.
        // So, there are assumptions that these 3 tender types have the same overtender-allowed value. 
        // The credit, debit and gift card overtender tender-type param values were combined into a single 
        // CreditDebitGiftCard param value to prevent the merchant from misconfiguring the values.
        // This code compensates for this change.  No longer can you simply compare tender-type to the
        // values in parameter "TendersNotAllowedForOvertender"
        if (TenderTypeEnum.CREDIT.toString().equals(tenderType)
                || TenderTypeEnum.DEBIT.toString().equals(tenderType)
                || TenderTypeEnum.GIFT_CARD.toString().equals(tenderType)) {
            return !isStringListed(ParameterConstantsIfc.TENDER_TendersNotAllowedForOvertender_CreditDebitGiftCard,
                    ParameterConstantsIfc.TENDER_TendersNotAllowedForOvertender);
        } else {
            return !isStringListed(tenderType, ParameterConstantsIfc.TENDER_TendersNotAllowedForOvertender);
        }
    }

}