org.kuali.kra.negotiations.lookup.NegotiationDaoOjb.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.kra.negotiations.lookup.NegotiationDaoOjb.java

Source

/*
 * Kuali Coeus, a comprehensive research administration system for higher education.
 * 
 * Copyright 2005-2015 Kuali, Inc.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kuali.kra.negotiations.lookup;

import org.apache.commons.lang3.StringUtils;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.broker.query.ReportQueryByCriteria;
import org.kuali.coeus.common.framework.version.VersionStatus;
import org.kuali.kra.award.home.Award;
import org.kuali.kra.institutionalproposal.home.InstitutionalProposal;
import org.kuali.kra.institutionalproposal.proposallog.ProposalLog;
import org.kuali.kra.negotiations.bo.Negotiation;
import org.kuali.kra.negotiations.bo.NegotiationAssociationType;
import org.kuali.kra.negotiations.bo.NegotiationUnassociatedDetail;
import org.kuali.kra.negotiations.service.NegotiationService;
import org.kuali.kra.subaward.bo.SubAward;
import org.kuali.rice.core.api.util.RiceKeyConstants;
import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
import org.kuali.rice.kns.service.KNSServiceLocator;
import org.kuali.rice.krad.bo.BusinessObject;
import org.kuali.rice.krad.dao.impl.LookupDaoOjb;
import org.kuali.rice.krad.lookup.CollectionIncomplete;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;
import org.springframework.dao.DataIntegrityViolationException;
import org.springmodules.orm.ojb.OjbOperationException;

import java.util.*;

/**
 * Negotiation Dao to assist with lookups. This implements looking up associated document information
 * as well as just negotiation info.
 */
public class NegotiationDaoOjb extends LookupDaoOjb implements NegotiationDao {

    private static final String ASSOC_PREFIX = "associatedNegotiable";
    private static final String NEGOTIATION_TYPE_ATTR = "negotiationAssociationTypeId";
    private static final String ASSOCIATED_DOC_ID_ATTR = "associatedDocumentId";
    private static final String INVALID_COLUMN_NAME = "NaN";

    private static Map<String, String> awardTransform;
    private static Map<String, String> proposalTransform;
    private static Map<String, String> proposalLogTransform;
    private static Map<String, String> unassociatedTransform;
    private static Map<String, String> subAwardTransform;

    private static Integer maxSearchResults;

    private NegotiationService negotiationService;

    static {
        awardTransform = new HashMap<String, String>();
        awardTransform.put("sponsorName", "sponsor.sponsorName");
        awardTransform.put("piName", "projectPersons.fullName");
        //proposal type code doesn't exist on the award so make sure we don't find awards when
        //search for proposal type
        awardTransform.put("negotiableProposalTypeCode", INVALID_COLUMN_NAME);
        awardTransform.put("leadUnitNumber", "unitNumber");
        awardTransform.put("leadUnitName", "leadUnit.unitName");
        awardTransform.put("subAwardRequisitionerId", INVALID_COLUMN_NAME);

        proposalTransform = new HashMap<String, String>();
        proposalTransform.put("sponsorName", "sponsor.sponsorName");
        proposalTransform.put("piName", "projectPersons.fullName");
        proposalTransform.put("leadUnitNumber", "unitNumber");
        proposalTransform.put("leadUnitName", "leadUnit.unitName");
        proposalTransform.put("negotiableProposalTypeCode", "proposalTypeCode");
        proposalTransform.put("subAwardRequisitionerId", INVALID_COLUMN_NAME);

        proposalLogTransform = new HashMap<String, String>();
        proposalLogTransform.put("sponsorName", "sponsor.sponsorName");
        proposalLogTransform.put("leadUnitNumber", "leadUnit");
        proposalLogTransform.put("leadUnitName", "unit.unitName");
        proposalLogTransform.put("negotiableProposalTypeCode", "proposalTypeCode");
        proposalLogTransform.put("subAwardRequisitionerId", INVALID_COLUMN_NAME);

        unassociatedTransform = new HashMap<String, String>();
        unassociatedTransform.put("sponsorName", "sponsor.sponsorName");
        unassociatedTransform.put("piName", "piName");
        //proposal type code doesn't exist here either so make sure we don't find then when
        //searching for proposal type
        unassociatedTransform.put("negotiableProposalTypeCode", INVALID_COLUMN_NAME);
        unassociatedTransform.put("leadUnitName", "leadUnit.unitName");
        unassociatedTransform.put("subAwardRequisitionerId", INVALID_COLUMN_NAME);

        subAwardTransform = new HashMap<String, String>();
        subAwardTransform.put("sponsorName", INVALID_COLUMN_NAME);
        subAwardTransform.put("sponsorCode", INVALID_COLUMN_NAME);
        subAwardTransform.put("piName", INVALID_COLUMN_NAME);
        subAwardTransform.put("negotiableProposalTypeCode", INVALID_COLUMN_NAME);
        subAwardTransform.put("leadUnitNumber", "unitNumber");
        subAwardTransform.put("leadUnitName", "leadUnit.unitName");
        subAwardTransform.put("subAwardRequisitionerId", "requisitionerId");

    }

    @SuppressWarnings("unchecked")
    @Override
    public Collection<Negotiation> getNegotiationResults(Map<String, String> fieldValues) {
        Map<String, String> associationDetails = new HashMap<String, String>();
        Iterator<Map.Entry<String, String>> iter = fieldValues.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = iter.next();
            if (StringUtils.startsWith(entry.getKey(), ASSOC_PREFIX)) {
                iter.remove();
                if (!StringUtils.isEmpty(entry.getValue())) {
                    associationDetails.put(entry.getKey().replaceFirst(ASSOC_PREFIX + ".", ""), entry.getValue());
                }
            }
        }

        Collection<Negotiation> result = new ArrayList<Negotiation>();
        if (!associationDetails.isEmpty()) {
            addListToList(result, getNegotiationsLinkedToAward(fieldValues, associationDetails));
            addListToList(result, getNegotiationsLinkedToProposal(fieldValues, associationDetails));
            addListToList(result, getNegotiationsLinkedToProposalLog(fieldValues, associationDetails));
            addListToList(result, getNegotiationsUnassociated(fieldValues, associationDetails));
            addListToList(result, getNegotiationsLinkedToSubAward(fieldValues, associationDetails));
        } else {
            result = findCollectionBySearchHelper(Negotiation.class, fieldValues, false, false, null);
        }
        if (result != null && !result.isEmpty() && StringUtils.isNotBlank(fieldValues.get("negotiationAge"))) {
            try {
                result = filterByNegotiationAge(fieldValues.get("negotiationAge"), result);
            } catch (NumberFormatException e) {
                GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS,
                        RiceKeyConstants.ERROR_CUSTOM,
                        new String[] { "Invalid Numeric Input: " + fieldValues.get("negotiationAge") });
                result = new ArrayList<Negotiation>();
            }
        }
        return result;
    }

    private void addListToList(Collection<Negotiation> fullResultList, Collection<Negotiation> listToAdd) {
        if (fullResultList != null && listToAdd != null) {
            Integer max = getNegotiatonSearchResultsLimit();
            if (max == null) {
                max = 500;
            }
            if (fullResultList.size() < max) {
                int fullResultListPlusListToAddSize = fullResultList.size() + listToAdd.size();
                if (fullResultListPlusListToAddSize <= max) {
                    fullResultList.addAll(listToAdd);
                } else {
                    int numberOfNewEntriesToAdd = max - fullResultList.size();
                    int counter = 1;
                    for (Negotiation neg : listToAdd) {
                        if (counter < numberOfNewEntriesToAdd) {
                            fullResultList.add(neg);
                        }
                        counter++;
                    }
                }
            }
        }
    }

    public Collection findCollectionBySearchHelper(Class businessObjectClass, Map formProps, boolean unbounded,
            boolean usePrimaryKeyValuesOnly, Object additionalCriteria) {
        BusinessObject businessObject = checkBusinessObjectClass(businessObjectClass);
        if (usePrimaryKeyValuesOnly) {
            return executeSearch(businessObjectClass,
                    getCollectionCriteriaFromMapUsingPrimaryKeysOnly(businessObjectClass, formProps), unbounded);
        }

        Criteria crit = getCollectionCriteriaFromMap(businessObject, formProps);
        if (additionalCriteria != null && additionalCriteria instanceof Criteria) {
            crit.addAndCriteria((Criteria) additionalCriteria);
        }

        return executeSearch(businessObjectClass, crit, unbounded);
    }

    private BusinessObject checkBusinessObjectClass(Class businessObjectClass) {
        if (businessObjectClass == null) {
            throw new IllegalArgumentException(
                    "BusinessObject class passed to LookupDaoOjb findCollectionBySearchHelper... method was null");
        }
        BusinessObject businessObject = null;
        try {
            businessObject = (BusinessObject) businessObjectClass.newInstance();
        } catch (IllegalAccessException e) {
            throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(),
                    e);
        } catch (InstantiationException e) {
            throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(),
                    e);
        }
        return businessObject;
    }

    private Collection executeSearch(Class businessObjectClass, Criteria criteria, boolean unbounded) {
        Collection searchResults = new ArrayList();
        Long matchingResultsCount = null;
        try {
            Integer searchResultsLimit = getNegotiatonSearchResultsLimit();
            if (!unbounded && (searchResultsLimit != null)) {
                matchingResultsCount = new Long(getPersistenceBrokerTemplate()
                        .getCount(QueryFactory.newQuery(businessObjectClass, criteria)));
                getDbPlatform().applyLimitSql(searchResultsLimit);
            }
            if ((matchingResultsCount == null)
                    || (matchingResultsCount.intValue() <= searchResultsLimit.intValue())) {
                matchingResultsCount = new Long(0);
            }
            searchResults = getPersistenceBrokerTemplate()
                    .getCollectionByQuery(QueryFactory.newQuery(businessObjectClass, criteria));
            // populate Person objects in business objects
            List bos = new ArrayList();
            bos.addAll(searchResults);
            searchResults = bos;
        } catch (OjbOperationException e) {
            throw new RuntimeException("NegotiationDaoOjb encountered exception during executeSearch", e);
        } catch (DataIntegrityViolationException e) {
            throw new RuntimeException("NegotiationDaoOjb encountered exception during executeSearch", e);
        }
        return new CollectionIncomplete(searchResults, matchingResultsCount);
    }

    private Integer getNegotiatonSearchResultsLimit() {
        if (maxSearchResults == null) {
            BusinessObjectEntry businessObjectEntry = (BusinessObjectEntry) KNSServiceLocator
                    .getDataDictionaryService().getDataDictionary().getBusinessObjectEntry("Negotiation");
            maxSearchResults = businessObjectEntry.getLookupDefinition().getResultSetLimit();
        }
        return maxSearchResults;
    }

    /**
     * Search for awards linked to negotiation using both award and negotiation values.
     * @param negotiationValues
     * @param associatedValues
     * @return
     */
    @SuppressWarnings("unchecked")
    protected Collection<Negotiation> getNegotiationsLinkedToAward(Map<String, String> negotiationValues,
            Map<String, String> associatedValues) {
        Map<String, String> values = transformMap(associatedValues, awardTransform);
        if (values == null) {
            return new ArrayList<Negotiation>();
        }
        values.put("awardSequenceStatus", VersionStatus.ACTIVE.name());
        Criteria criteria = getCollectionCriteriaFromMap(new Award(), values);
        Criteria negotiationCrit = new Criteria();
        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(Award.class, criteria);
        subQuery.setAttributes(new String[] { "awardNumber" });
        negotiationCrit.addIn(ASSOCIATED_DOC_ID_ATTR, subQuery);
        negotiationCrit.addEqualTo(NEGOTIATION_TYPE_ATTR, getNegotiationService()
                .getNegotiationAssociationType(NegotiationAssociationType.AWARD_ASSOCIATION).getId());
        Collection<Negotiation> result = this.findCollectionBySearchHelper(Negotiation.class, negotiationValues,
                false, false, negotiationCrit);
        return result;
    }

    /**
     * Search for institutional proposals linked to negotiations using both criteria.
     * @param negotiationValues
     * @param associatedValues
     * @return
     */
    @SuppressWarnings("unchecked")
    protected Collection<Negotiation> getNegotiationsLinkedToProposal(Map<String, String> negotiationValues,
            Map<String, String> associatedValues) {
        Map<String, String> values = transformMap(associatedValues, proposalTransform);
        if (values == null) {
            return new ArrayList<Negotiation>();
        }
        values.put("proposalSequenceStatus", VersionStatus.ACTIVE.name());
        Criteria criteria = getCollectionCriteriaFromMap(new InstitutionalProposal(), values);
        Criteria negotiationCrit = new Criteria();
        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(InstitutionalProposal.class, criteria);
        subQuery.setAttributes(new String[] { "proposalNumber" });
        negotiationCrit.addIn(ASSOCIATED_DOC_ID_ATTR, subQuery);
        negotiationCrit.addEqualTo(NEGOTIATION_TYPE_ATTR, getNegotiationService()
                .getNegotiationAssociationType(NegotiationAssociationType.INSTITUATIONAL_PROPOSAL_ASSOCIATION)
                .getId());
        Collection<Negotiation> result = this.findCollectionBySearchHelper(Negotiation.class, negotiationValues,
                false, false, negotiationCrit);
        return result;
    }

    /**
     * Search for proposal logs linked to negotiations using both criteria.
     * @param negotiationValues
     * @param associatedValues
     * @return
     */
    @SuppressWarnings("unchecked")
    protected Collection<Negotiation> getNegotiationsLinkedToProposalLog(Map<String, String> negotiationValues,
            Map<String, String> associatedValues) {
        Map<String, String> values = transformMap(associatedValues, proposalLogTransform);
        if (values == null) {
            return new ArrayList<Negotiation>();
        }
        Criteria criteria = getCollectionCriteriaFromMap(new ProposalLog(), values);
        Criteria negotiationCrit = new Criteria();
        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(ProposalLog.class, criteria);
        subQuery.setAttributes(new String[] { "proposalNumber" });
        negotiationCrit.addIn(ASSOCIATED_DOC_ID_ATTR, subQuery);
        negotiationCrit.addEqualTo(NEGOTIATION_TYPE_ATTR, getNegotiationService()
                .getNegotiationAssociationType(NegotiationAssociationType.PROPOSAL_LOG_ASSOCIATION).getId());
        Collection<Negotiation> result = this.findCollectionBySearchHelper(Negotiation.class, negotiationValues,
                false, false, negotiationCrit);
        return result;
    }

    /**
     * 
     * This method returns Negotiations linked to subawards based on search.
     * @param negotiationValues
     * @param associatedValues
     * @return
     */
    protected Collection<Negotiation> getNegotiationsLinkedToSubAward(Map<String, String> negotiationValues,
            Map<String, String> associatedValues) {

        Map<String, String> values = transformMap(associatedValues, subAwardTransform);
        if (values == null) {
            return new ArrayList<Negotiation>();
        }
        Criteria criteria = getCollectionCriteriaFromMap(new SubAward(), values);
        Criteria negotiationCrit = new Criteria();
        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(SubAward.class, criteria);
        subQuery.setAttributes(new String[] { "subAwardId" });
        negotiationCrit.addIn(ASSOCIATED_DOC_ID_ATTR, subQuery);
        negotiationCrit.addEqualTo(NEGOTIATION_TYPE_ATTR, getNegotiationService()
                .getNegotiationAssociationType(NegotiationAssociationType.SUB_AWARD_ASSOCIATION).getId());
        Collection<Negotiation> result = this.findCollectionBySearchHelper(Negotiation.class, negotiationValues,
                false, false, negotiationCrit);

        return result;
    }

    /**
     * Search for unassociated negotiations using criteria from the unassociated detail.
     * @param negotiationValues
     * @param associatedValues
     * @return
     */
    @SuppressWarnings("unchecked")
    protected Collection<Negotiation> getNegotiationsUnassociated(Map<String, String> negotiationValues,
            Map<String, String> associatedValues) {
        Map<String, String> values = transformMap(associatedValues, unassociatedTransform);
        if (values == null) {
            return new ArrayList<Negotiation>();
        }
        Criteria criteria = getCollectionCriteriaFromMap(new NegotiationUnassociatedDetail(), values);
        Criteria negotiationCrit = new Criteria();
        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(NegotiationUnassociatedDetail.class, criteria);
        subQuery.setAttributes(new String[] { "negotiationUnassociatedDetailId" });
        negotiationCrit.addIn(ASSOCIATED_DOC_ID_ATTR, subQuery);
        negotiationCrit.addEqualTo(NEGOTIATION_TYPE_ATTR, getNegotiationService()
                .getNegotiationAssociationType(NegotiationAssociationType.NONE_ASSOCIATION).getId());
        Collection<Negotiation> result = this.findCollectionBySearchHelper(Negotiation.class, negotiationValues,
                false, false, negotiationCrit);
        return result;
    }

    /**
     * Take the associated field values and convert them to document specific values using the provided
     * transform key.
     * @param values
     * @param transformKey
     * @return
     */
    protected Map<String, String> transformMap(Map<String, String> values, Map<String, String> transformKey) {
        Map<String, String> result = new HashMap<String, String>();
        for (Map.Entry<String, String> entry : values.entrySet()) {
            if (transformKey.get(entry.getKey()) != null) {
                result.put(transformKey.get(entry.getKey()), entry.getValue());
            } else {
                result.put(entry.getKey(), entry.getValue());
            }
        }
        if (result.containsKey(INVALID_COLUMN_NAME)) {
            return null;
        } else {
            return result;
        }
    }

    /**
     * Since the negotiation age is not persisted filter negotiations based on age.
     * @param value
     * @param negotiations
     * @return
     */
    protected Collection<Negotiation> filterByNegotiationAge(String value, Collection<Negotiation> negotiations) {
        int lowValue = 0;
        int highValue = 0;
        boolean greaterThan = false;
        boolean lessThan = false;
        boolean between = false;
        if (value.contains(">")) {
            greaterThan = true;
            lowValue = Integer.parseInt(value.replace(">", ""));
        } else if (value.contains("<")) {
            lessThan = true;
            highValue = Integer.parseInt(value.replace("<", ""));
        } else if (value.contains("..")) {
            between = true;
            String[] values = value.split("\\.\\.");
            lowValue = Integer.parseInt(values[0]);
            highValue = Integer.parseInt(values[1]);
        } else {
            lowValue = Integer.parseInt(value);
        }
        Iterator<Negotiation> iter = negotiations.iterator();
        while (iter.hasNext()) {
            Negotiation negotiation = iter.next();
            if (greaterThan) {
                if (negotiation.getNegotiationAge() <= lowValue) {
                    iter.remove();
                }
            } else if (lessThan) {
                if (negotiation.getNegotiationAge() >= highValue) {
                    iter.remove();
                }
            } else if (between) {
                if (negotiation.getNegotiationAge() < lowValue || negotiation.getNegotiationAge() > highValue) {
                    iter.remove();
                }
            } else {
                if (negotiation.getNegotiationAge() != lowValue) {
                    iter.remove();
                }
            }
        }

        return negotiations;
    }

    public NegotiationService getNegotiationService() {
        return negotiationService;
    }

    public void setNegotiationService(NegotiationService negotiationService) {
        this.negotiationService = negotiationService;
    }

}