Example usage for java.util Set equals

List of usage examples for java.util Set equals

Introduction

In this page you can find the example usage for java.util Set equals.

Prototype

boolean equals(Object o);

Source Link

Document

Compares the specified object with this set for equality.

Usage

From source file:pcgen.core.Equipment.java

/**
 * Returns a list of the types of this item.
 * /*from  w ww  . jav a2  s.  c  o  m*/
 * @param bPrimary
 *            if true return the types if the primary head, otherwise
 *            return the types of the secondary head
 * @return a list of the types of this item.
 */
private List<String> typeList(final boolean bPrimary) {

    if (bPrimary && usePrimaryCache) {
        return typeListCachePrimary;
    }
    if (!bPrimary && useSecondaryCache) {
        return typeListCacheSecondary;
    }

    // Use the primary type(s) if none defined for secondary
    List<Type> initializingList = getEquipmentHead(2).getListFor(ListKey.TYPE);
    if (bPrimary || (initializingList == null) || initializingList.isEmpty()) {
        initializingList = getTrueTypeList(false);
    } else if (!isDouble()) {
        return new ArrayList<>();
    }

    Set<String> calculatedTypeList = new LinkedHashSet<>();
    if (initializingList != null) {
        for (Type t : initializingList) {
            calculatedTypeList.add(t.getComparisonString());
        }
    }
    final Collection<String> modTypeList = new ArrayList<>();

    //
    // Add in all type modfiers from "ADDTYPE" modifier
    //
    EquipmentModifier aEqMod = getEqModifierKeyed("ADDTYPE", bPrimary);

    if (aEqMod != null) {
        for (String aType : getAssociationList(aEqMod)) {
            aType = aType.toUpperCase();

            if (!calculatedTypeList.contains(aType)) {
                modTypeList.add(aType);
            }
        }
    }

    /*
     * CONSIDER I think there is a weird order of operations issue nere, need to check
     * if it existed way back, e.g. SVN 6206.  The issue is if a Type is introduced by a 
     * MOD, then the ChangeArmorType system doesn't seem to be able to grab/modify it
     * Is that correct? - thpr 10/3/08
     */
    //
    // Add in all of the types from each EquipmentModifier
    // currently applied to this piece of equipment
    //
    final List<EquipmentModifier> eqModList = getEqModifierList(bPrimary);

    for (EquipmentModifier eqMod : eqModList) {
        //
        // If we've just replaced the armor type, then make sure it is
        // not in the equipment modifier list
        //
        Set<String> newTypeList = new LinkedHashSet<>(calculatedTypeList);
        for (ChangeArmorType cat : eqMod.getSafeListFor(ListKey.ARMORTYPE)) {
            List<String> tempTypeList = cat.applyProcessor(newTypeList);
            LinkedHashSet<String> tempTypeSet = new LinkedHashSet<>(tempTypeList);
            boolean noMatch = newTypeList.size() != tempTypeList.size() || newTypeList.equals(tempTypeSet);
            newTypeList = tempTypeSet;
            if (!noMatch) {
                break;
            }
        }

        Collection<String> removedTypeList = new ArrayList<>(calculatedTypeList);
        removedTypeList.removeAll(newTypeList);
        modTypeList.removeAll(removedTypeList);
        calculatedTypeList = newTypeList;

        for (String aType : eqMod.getSafeListFor(ListKey.ITEM_TYPES)) {
            aType = aType.toUpperCase();

            // If it's BOTH & MELEE, we cannot add RANGED or THROWN to
            // it
            // BOTH is only used after the split of a Thrown weapon in 2
            // (melee and ranged)
            if (calculatedTypeList.contains("BOTH") && calculatedTypeList.contains("MELEE")
                    && ("RANGED".equals(aType) || "THROWN".equals(aType))) {
                continue;
            }

            if (!calculatedTypeList.contains(aType) && !modTypeList.contains(aType)) {
                modTypeList.add(aType);
            }
        }
    }

    calculatedTypeList.addAll(modTypeList);

    //
    // Make sure MAGIC tag is the 1st entry
    //
    List<String> resultingTypeList = new ArrayList<>(calculatedTypeList);
    final int idx = resultingTypeList.indexOf("MAGIC");

    if (idx > 0) {
        resultingTypeList.remove(idx);
        resultingTypeList.add(0, "MAGIC");
    }

    if (bPrimary) {
        typeListCachePrimary = resultingTypeList;
        usePrimaryCache = true;
    } else {
        typeListCacheSecondary = resultingTypeList;
        useSecondaryCache = true;
    }
    return resultingTypeList;
}

From source file:org.opendaylight.vtn.manager.it.northbound.VtnNorthboundIT.java

/**
 * Check the MAC address table in the given vBridge.
 *
 * @param uri       A URI that indicates the MAC address table.
 * @param expected  A set of expected MAC address table entries.
 * @param doAssert  If {@code true}, an error will be thrown on failure.
 * @return  {@code true} only if the check passed.
 * @throws Exception  An error occurred.
 *//*from  www  .  ja v a  2  s  .c o  m*/
private boolean checkMacTableEntry(String uri, Set<MacAddressEntry> expected, boolean doAssert)
        throws Exception {
    String res = getJsonResult(uri);
    assertResponse(HTTP_OK);

    JSONTokener jt = new JSONTokener(res);
    JSONObject json = new JSONObject(jt);
    JSONArray macArray = json.getJSONArray("macentry");
    if (doAssert) {
        assertEquals(expected.size(), macArray.length());
    } else if (expected.size() != macArray.length()) {
        return false;
    }

    Set<MacAddressEntry> result = new HashSet<>();
    for (int i = 0; i < macArray.length(); i++) {
        JSONObject jobj = macArray.getJSONObject(i);
        assertTrue(result.add(toMacAddressEntry(jobj)));
    }

    if (doAssert) {
        assertEquals(expected, result);
    } else if (!expected.equals(result)) {
        return false;
    }

    return true;
}

From source file:com.xpn.xwiki.doc.XWikiDocument.java

@Override
public boolean equals(Object object) {
    // Same Java object, they sure are equal
    if (this == object) {
        return true;
    }/*from  w  ww  .j  a v  a2 s.com*/

    XWikiDocument doc = (XWikiDocument) object;
    if (!getDocumentReference().equals(doc.getDocumentReference())) {
        return false;
    }

    if (!ObjectUtils.equals(getAuthorReference(), doc.getAuthorReference())) {
        return false;
    }

    if (!ObjectUtils.equals(getContentAuthorReference(), doc.getContentAuthorReference())) {
        return false;
    }

    if (!ObjectUtils.equals(getParentReference(), doc.getParentReference())) {
        return false;
    }

    if (!ObjectUtils.equals(getCreatorReference(), doc.getCreatorReference())) {
        return false;
    }

    if (!getDefaultLanguage().equals(doc.getDefaultLanguage())) {
        return false;
    }

    if (!getLanguage().equals(doc.getLanguage())) {
        return false;
    }

    if (getTranslation() != doc.getTranslation()) {
        return false;
    }

    if (getDate().getTime() != doc.getDate().getTime()) {
        return false;
    }

    if (getContentUpdateDate().getTime() != doc.getContentUpdateDate().getTime()) {
        return false;
    }

    if (getCreationDate().getTime() != doc.getCreationDate().getTime()) {
        return false;
    }

    if (!getFormat().equals(doc.getFormat())) {
        return false;
    }

    if (!getTitle().equals(doc.getTitle())) {
        return false;
    }

    if (!getContent().equals(doc.getContent())) {
        return false;
    }

    if (!getVersion().equals(doc.getVersion())) {
        return false;
    }

    if (!ObjectUtils.equals(getTemplateDocumentReference(), doc.getTemplateDocumentReference())) {
        return false;
    }

    if (!getDefaultTemplate().equals(doc.getDefaultTemplate())) {
        return false;
    }

    if (!getValidationScript().equals(doc.getValidationScript())) {
        return false;
    }

    if (!getComment().equals(doc.getComment())) {
        return false;
    }

    if (isMinorEdit() != doc.isMinorEdit()) {
        return false;
    }

    if (!ObjectUtils.equals(getSyntax(), doc.getSyntax())) {
        return false;
    }

    if (isHidden() != doc.isHidden()) {
        return false;
    }

    if (!getXClass().equals(doc.getXClass())) {
        return false;
    }

    Set<DocumentReference> myObjectClassReferences = getXObjects().keySet();
    Set<DocumentReference> otherObjectClassReferences = doc.getXObjects().keySet();
    if (!myObjectClassReferences.equals(otherObjectClassReferences)) {
        return false;
    }

    for (DocumentReference reference : myObjectClassReferences) {
        List<BaseObject> myObjects = getXObjects(reference);
        List<BaseObject> otherObjects = doc.getXObjects(reference);
        if (myObjects.size() != otherObjects.size()) {
            return false;
        }
        for (int i = 0; i < myObjects.size(); i++) {
            if ((myObjects.get(i) == null && otherObjects.get(i) != null)
                    || (myObjects.get(i) != null && otherObjects.get(i) == null)) {
                return false;
            }
            if (myObjects.get(i) == null && otherObjects.get(i) == null) {
                continue;
            }
            if (!myObjects.get(i).equals(otherObjects.get(i))) {
                return false;
            }
        }
    }

    // We consider that 2 documents are still equal even when they have different original
    // documents (see getOriginalDocument() for more details as to what is an original
    // document).

    return true;
}

From source file:com.net2plan.interfaces.networkDesign.NetPlan.java

/**
 * <p>Checks if a set of links is valid for a given multicast demand. If it is not, an exception will be thrown. If it is valid, a map is returned with the
 * unique sequence of links in the tree, from the ingress node to each egress node of the multicast demand.</p>
 *
 * @param linkSet Sequence of links//  w  w w .  j av a  2 s  .c om
 * @param demand  Multicast demand
 * @return Map where the keys are nodes and the values are sequences of links (see description)
 * @see com.net2plan.interfaces.networkDesign.Node
 * @see com.net2plan.interfaces.networkDesign.Link
 * @see com.net2plan.interfaces.networkDesign.MulticastDemand
 */
Pair<Map<Node, List<Link>>, Set<Node>> checkMulticastTreeValidityForDemand(Set<Link> linkSet,
        MulticastDemand demand) {
    if (linkSet.isEmpty())
        throw new Net2PlanException("The multicast tree is empty");
    checkInThisNetPlan(demand);
    final NetworkLayer layer = demand.layer;
    checkInThisNetPlanAndLayer(linkSet, demand.layer);

    Map<Node, List<Link>> pathToEgressNode = new HashMap<Node, List<Link>>();
    Map<Link, Double> linkCost = new HashMap<Link, Double>();
    for (Link link : layer.links)
        linkCost.put(link, (linkSet.contains(link)) ? 1 : Double.MAX_VALUE);
    Set<Link> actuallyTraversedLinks = new HashSet<Link>();
    for (Node egressNode : demand.egressNodes) {
        final List<Link> seqLinks = GraphUtils.getShortestPath(nodes, layer.links, demand.ingressNode,
                egressNode, linkCost);
        if (seqLinks == null)
            throw new Net2PlanException("No path to an end node");
        pathToEgressNode.put(egressNode, seqLinks);
        actuallyTraversedLinks.addAll(seqLinks);
    }

    if (!linkSet.equals(actuallyTraversedLinks))
        throw new Net2PlanException(
                "Some links in the link set provided are not traversed. The structure may not be a tree");

    Set<Node> traversedNodes = new HashSet<Node>();
    for (Link e : linkSet) {
        traversedNodes.add(e.originNode);
        traversedNodes.add(e.destinationNode);
    }
    if (traversedNodes.size() != linkSet.size() + 1)
        throw new Net2PlanException("It is not a tree");

    return Pair.of(pathToEgressNode, traversedNodes);
}

From source file:org.mifosplatform.portfolio.loanaccount.domain.Loan.java

public Map<String, Object> loanApplicationModification(final JsonCommand command,
        final Set<LoanCharge> possiblyModifedLoanCharges,
        final Set<LoanCollateral> possiblyModifedLoanCollateralItems, final AprCalculator aprCalculator,
        final Set<LoanFeeMaster> possiblyModifedLoanDeposits) {

    final Map<String, Object> actualChanges = this.loanRepaymentScheduleDetail
            .updateLoanApplicationAttributes(command, aprCalculator);
    if (!actualChanges.isEmpty()) {
        final boolean recalculateLoanSchedule = !(actualChanges.size() == 1
                && actualChanges.containsKey("inArrearsTolerance"));
        actualChanges.put("recalculateLoanSchedule", recalculateLoanSchedule);
    }/*  w  w w  .jav  a 2 s .  c  om*/

    final String dateFormatAsInput = command.dateFormat();
    final String localeAsInput = command.locale();

    final String accountNoParamName = "accountNo";
    if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) {
        final String newValue = command.stringValueOfParameterNamed(accountNoParamName);
        actualChanges.put(accountNoParamName, newValue);
        this.accountNumber = StringUtils.defaultIfEmpty(newValue, null);
    }

    final String externalIdParamName = "externalId";
    if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
        final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.externalId = StringUtils.defaultIfEmpty(newValue, null);
    }

    // add clientId, groupId and loanType changes to actual changes

    final String clientIdParamName = "clientId";
    final Long clientId = this.client == null ? null : this.client.getId();
    if (command.isChangeInLongParameterNamed(clientIdParamName, clientId)) {
        final Long newValue = command.longValueOfParameterNamed(clientIdParamName);
        actualChanges.put(clientIdParamName, newValue);
    }

    // FIXME: AA - We may require separate api command to move loan from one
    // group to another
    final String groupIdParamName = "groupId";
    final Long groupId = this.group == null ? null : this.group.getId();
    if (command.isChangeInLongParameterNamed(groupIdParamName, groupId)) {
        final Long newValue = command.longValueOfParameterNamed(groupIdParamName);
        actualChanges.put(groupIdParamName, newValue);
    }

    final String productIdParamName = "productId";
    if (command.isChangeInLongParameterNamed(productIdParamName, this.loanProduct.getId())) {
        final Long newValue = command.longValueOfParameterNamed(productIdParamName);
        actualChanges.put(productIdParamName, newValue);
        actualChanges.put("recalculateLoanSchedule", true);
    }

    Long existingFundId = null;
    if (this.fund != null) {
        existingFundId = this.fund.getId();
    }
    final String fundIdParamName = "fundId";
    if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) {
        final Long newValue = command.longValueOfParameterNamed(fundIdParamName);
        actualChanges.put(fundIdParamName, newValue);
    }

    Long existingLoanOfficerId = null;
    if (this.loanOfficer != null) {
        existingLoanOfficerId = this.loanOfficer.getId();
    }
    final String loanOfficerIdParamName = "loanOfficerId";
    if (command.isChangeInLongParameterNamed(loanOfficerIdParamName, existingLoanOfficerId)) {
        final Long newValue = command.longValueOfParameterNamed(loanOfficerIdParamName);
        actualChanges.put(loanOfficerIdParamName, newValue);
    }

    Long existingLoanPurposeId = null;
    if (this.loanPurpose != null) {
        existingLoanPurposeId = this.loanPurpose.getId();
    }
    final String loanPurposeIdParamName = "loanPurposeId";
    if (command.isChangeInLongParameterNamed(loanPurposeIdParamName, existingLoanPurposeId)) {
        final Long newValue = command.longValueOfParameterNamed(loanPurposeIdParamName);
        actualChanges.put(loanPurposeIdParamName, newValue);
    }

    final String strategyIdParamName = "transactionProcessingStrategyId";
    if (command.isChangeInLongParameterNamed(strategyIdParamName, this.transactionProcessingStrategy.getId())) {
        final Long newValue = command.longValueOfParameterNamed(strategyIdParamName);
        actualChanges.put(strategyIdParamName, newValue);
    }

    final String submittedOnDateParamName = "submittedOnDate";
    if (command.isChangeInLocalDateParameterNamed(submittedOnDateParamName, getSubmittedOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(submittedOnDateParamName);
        actualChanges.put(submittedOnDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);

        final LocalDate newValue = command.localDateValueOfParameterNamed(submittedOnDateParamName);
        this.submittedOnDate = newValue.toDate();
    }

    final String expectedDisbursementDateParamName = "expectedDisbursementDate";
    if (command.isChangeInLocalDateParameterNamed(expectedDisbursementDateParamName,
            getExpectedDisbursedOnLocalDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(expectedDisbursementDateParamName);
        actualChanges.put(expectedDisbursementDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(expectedDisbursementDateParamName);
        this.expectedDisbursementDate = newValue.toDate();
        removeFirstDisbursementTransaction();
    }

    final String repaymentsStartingFromDateParamName = "repaymentsStartingFromDate";
    if (command.isChangeInLocalDateParameterNamed(repaymentsStartingFromDateParamName,
            getExpectedFirstRepaymentOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(repaymentsStartingFromDateParamName);
        actualChanges.put(repaymentsStartingFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(repaymentsStartingFromDateParamName);
        if (newValue != null) {
            this.expectedFirstRepaymentOnDate = newValue.toDate();
        } else {
            this.expectedFirstRepaymentOnDate = null;
        }
    }

    final String syncDisbursementParameterName = "syncDisbursementWithMeeting";
    if (command.isChangeInBooleanParameterNamed(syncDisbursementParameterName,
            isSyncDisbursementWithMeeting())) {
        final Boolean valueAsInput = command.booleanObjectValueOfParameterNamed(syncDisbursementParameterName);
        actualChanges.put(syncDisbursementParameterName, valueAsInput);
        this.syncDisbursementWithMeeting = valueAsInput;
    }

    final String interestChargedFromDateParamName = "interestChargedFromDate";
    if (command.isChangeInLocalDateParameterNamed(interestChargedFromDateParamName,
            getInterestChargedFromDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(interestChargedFromDateParamName);
        actualChanges.put(interestChargedFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(interestChargedFromDateParamName);
        if (newValue != null) {
            this.interestChargedFromDate = newValue.toDate();
        } else {
            this.interestChargedFromDate = null;
        }
    }

    if (getSubmittedOnDate().isAfter(new LocalDate())) {
        final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage,
                getSubmittedOnDate());
    }

    if (!(this.client == null)) {
        if (getSubmittedOnDate().isBefore(this.client.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than client's activation date.";
            throw new InvalidLoanStateTransitionException("submittal",
                    "cannot.be.before.client.activation.date", errorMessage, getSubmittedOnDate());
        }
    } else if (!(this.group == null)) {
        if (getSubmittedOnDate().isBefore(this.group.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
            throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date",
                    errorMessage, getSubmittedOnDate());
        }
    }

    if (getSubmittedOnDate().isAfter(getExpectedDisbursedOnLocalDate())) {
        final String errorMessage = "The date on which a loan is submitted cannot be after its expected disbursement date: "
                + getExpectedDisbursedOnLocalDate().toString();
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.after.expected.disbursement.date",
                errorMessage, getSubmittedOnDate(), getExpectedDisbursedOnLocalDate());
    }

    final String chargesParamName = "charges";
    if (command.parameterExists(chargesParamName)) {

        final Set<LoanCharge> existingLoanCharges = setOfLoanCharges();

        if (!possiblyModifedLoanCharges.equals(existingLoanCharges)) {
            actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges));

            actualChanges.put("recalculateLoanSchedule", true);

            for (final LoanCharge loanCharge : possiblyModifedLoanCharges) {
                final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
                BigDecimal chargeAmt = BigDecimal.ZERO;
                BigDecimal totalChargeAmt = BigDecimal.ZERO;
                if (loanCharge.getChargeCalculation().isPercentageBased()) {
                    chargeAmt = loanCharge.getPercentage();
                    if (loanCharge.isInstalmentFee()) {
                        totalChargeAmt = calculatePerInstallmentChargeAmount(loanCharge);
                    }
                } else {
                    chargeAmt = loanCharge.amount();
                    if (loanCharge.isInstalmentFee()) {
                        chargeAmt = chargeAmt
                                .divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments()));
                    }
                }
                loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount,
                        repaymentScheduleDetail().getNumberOfRepayments(), totalChargeAmt);
                validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(),
                        getLastRepaymentPeriodDueDate());
            }
        }
    }

    final String collateralParamName = "collateral";
    if (command.parameterExists(collateralParamName)) {

        if (!possiblyModifedLoanCollateralItems.equals(this.collateral)) {
            actualChanges.put(collateralParamName,
                    listOfLoanCollateralData(possiblyModifedLoanCollateralItems));
        }
    }

    final String loanTermFrequencyParamName = "loanTermFrequency";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyParamName, this.termFrequency)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.termFrequency = newValue;
    }

    final String loanTermFrequencyTypeParamName = "loanTermFrequencyType";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyTypeParamName, this.termPeriodFrequencyType)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyTypeParamName);
        final PeriodFrequencyType newTermPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
        actualChanges.put(loanTermFrequencyTypeParamName, newTermPeriodFrequencyType.getValue());
        this.termPeriodFrequencyType = newValue;
    }

    final String depositsParamName = "depositArray";
    if (command.parameterExists(depositsParamName)) {

        final Set<LoanFeeMaster> existingLoanDeposits = setOfLoanDeposits();

        if (!possiblyModifedLoanDeposits.equals(existingLoanDeposits)) {

            actualChanges.put(depositsParamName, getLoanDeposit(possiblyModifedLoanDeposits));
            actualChanges.put("recalculateLoanSchedule", true);

            for (final LoanFeeMaster loanDeposit : possiblyModifedLoanDeposits) {
                final BigDecimal amount = calculateAmountPercentageAppliedTo(loanDeposit);
                BigDecimal depositAmt = BigDecimal.ZERO;
                if (loanDeposit.getDepositCalculation().isPercentageBased()) {
                    depositAmt = loanDeposit.getPercentage();
                } else {
                    depositAmt = loanDeposit.getAmount();
                }
                loanDeposit.update(depositAmt, amount, BigDecimal.ZERO);
            }
        }
    }

    return actualChanges;
}

From source file:org.sakaiproject.assignment.tool.AssignmentAction.java

/**
 * Determines if the attachments have been modified
 * @return true if currentAttachments isn't equal to oldAttachments
 *///from   w ww .  j a  v a 2 s . co m
private boolean areAttachmentsModified(List oldAttachments, List currentAttachments) {
    boolean hasCurrent = CollectionUtils.isNotEmpty(currentAttachments);
    boolean hasOld = CollectionUtils.isNotEmpty(oldAttachments);

    if (!hasCurrent) {
        //there are no current attachments
        return hasOld;
    }
    if (!hasOld) {
        //there are no old attachments (and there are new ones)
        return true;
    }

    Set<String> ids1 = getIdsFromReferences(oldAttachments);
    Set<String> ids2 = getIdsFromReferences(currentAttachments);

    //.equals on Sets of Strings will compare .equals on the contained Strings
    return !ids1.equals(ids2);
}

From source file:org.apache.fineract.portfolio.loanaccount.domain.Loan.java

public Map<String, Object> loanApplicationModification(final JsonCommand command,
        final Set<LoanCharge> possiblyModifedLoanCharges,
        final Set<LoanCollateral> possiblyModifedLoanCollateralItems, final AprCalculator aprCalculator,
        boolean isChargesModified) {

    final Map<String, Object> actualChanges = this.loanRepaymentScheduleDetail
            .updateLoanApplicationAttributes(command, aprCalculator);
    if (!actualChanges.isEmpty()) {
        final boolean recalculateLoanSchedule = !(actualChanges.size() == 1
                && actualChanges.containsKey("inArrearsTolerance"));
        actualChanges.put("recalculateLoanSchedule", recalculateLoanSchedule);
        isChargesModified = true;/*from w  ww . j ava2s .  c om*/
    }

    final String dateFormatAsInput = command.dateFormat();
    final String localeAsInput = command.locale();
    final LocalDate recalculationRestFrequencyDate = command
            .localDateValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyDateParamName);
    final LocalDate recalculationCompoundingFrequencyDate = command.localDateValueOfParameterNamed(
            LoanProductConstants.recalculationCompoundingFrequencyDateParamName);
    updateLoanInterestRecalculationSettings(recalculationRestFrequencyDate,
            recalculationCompoundingFrequencyDate, command, actualChanges);

    final String accountNoParamName = "accountNo";
    if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) {
        final String newValue = command.stringValueOfParameterNamed(accountNoParamName);
        actualChanges.put(accountNoParamName, newValue);
        this.accountNumber = StringUtils.defaultIfEmpty(newValue, null);
    }

    final String createSiAtDisbursementParameterName = "createStandingInstructionAtDisbursement";
    if (command.isChangeInBooleanParameterNamed(createSiAtDisbursementParameterName,
            shouldCreateStandingInstructionAtDisbursement())) {
        final Boolean valueAsInput = command
                .booleanObjectValueOfParameterNamed(createSiAtDisbursementParameterName);
        actualChanges.put(createSiAtDisbursementParameterName, valueAsInput);
        this.createStandingInstructionAtDisbursement = valueAsInput;
    }

    final String externalIdParamName = "externalId";
    if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
        final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.externalId = StringUtils.defaultIfEmpty(newValue, null);
    }

    // add clientId, groupId and loanType changes to actual changes

    final String clientIdParamName = "clientId";
    final Long clientId = this.client == null ? null : this.client.getId();
    if (command.isChangeInLongParameterNamed(clientIdParamName, clientId)) {
        final Long newValue = command.longValueOfParameterNamed(clientIdParamName);
        actualChanges.put(clientIdParamName, newValue);
    }

    // FIXME: AA - We may require separate api command to move loan from one
    // group to another
    final String groupIdParamName = "groupId";
    final Long groupId = this.group == null ? null : this.group.getId();
    if (command.isChangeInLongParameterNamed(groupIdParamName, groupId)) {
        final Long newValue = command.longValueOfParameterNamed(groupIdParamName);
        actualChanges.put(groupIdParamName, newValue);
    }

    final String productIdParamName = "productId";
    if (command.isChangeInLongParameterNamed(productIdParamName, this.loanProduct.getId())) {
        final Long newValue = command.longValueOfParameterNamed(productIdParamName);
        actualChanges.put(productIdParamName, newValue);
        actualChanges.put("recalculateLoanSchedule", true);
    }

    final String isFloatingInterestRateParamName = "isFloatingInterestRate";
    if (command.isChangeInBooleanParameterNamed(isFloatingInterestRateParamName, this.isFloatingInterestRate)) {
        final Boolean newValue = command.booleanObjectValueOfParameterNamed(isFloatingInterestRateParamName);
        actualChanges.put(isFloatingInterestRateParamName, newValue);
        this.isFloatingInterestRate = newValue;
    }

    final String interestRateDifferentialParamName = "interestRateDifferential";
    if (command.isChangeInBigDecimalParameterNamed(interestRateDifferentialParamName,
            this.interestRateDifferential)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateDifferentialParamName);
        actualChanges.put(interestRateDifferentialParamName, newValue);
        this.interestRateDifferential = newValue;
    }

    Long existingFundId = null;
    if (this.fund != null) {
        existingFundId = this.fund.getId();
    }
    final String fundIdParamName = "fundId";
    if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) {
        final Long newValue = command.longValueOfParameterNamed(fundIdParamName);
        actualChanges.put(fundIdParamName, newValue);
    }

    Long existingLoanOfficerId = null;
    if (this.loanOfficer != null) {
        existingLoanOfficerId = this.loanOfficer.getId();
    }
    final String loanOfficerIdParamName = "loanOfficerId";
    if (command.isChangeInLongParameterNamed(loanOfficerIdParamName, existingLoanOfficerId)) {
        final Long newValue = command.longValueOfParameterNamed(loanOfficerIdParamName);
        actualChanges.put(loanOfficerIdParamName, newValue);
    }

    Long existingLoanPurposeId = null;
    if (this.loanPurpose != null) {
        existingLoanPurposeId = this.loanPurpose.getId();
    }
    final String loanPurposeIdParamName = "loanPurposeId";
    if (command.isChangeInLongParameterNamed(loanPurposeIdParamName, existingLoanPurposeId)) {
        final Long newValue = command.longValueOfParameterNamed(loanPurposeIdParamName);
        actualChanges.put(loanPurposeIdParamName, newValue);
    }

    final String strategyIdParamName = "transactionProcessingStrategyId";
    if (command.isChangeInLongParameterNamed(strategyIdParamName, this.transactionProcessingStrategy.getId())) {
        final Long newValue = command.longValueOfParameterNamed(strategyIdParamName);
        actualChanges.put(strategyIdParamName, newValue);
    }

    final String submittedOnDateParamName = "submittedOnDate";
    if (command.isChangeInLocalDateParameterNamed(submittedOnDateParamName, getSubmittedOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(submittedOnDateParamName);
        actualChanges.put(submittedOnDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);

        final LocalDate newValue = command.localDateValueOfParameterNamed(submittedOnDateParamName);
        this.submittedOnDate = newValue.toDate();
    }

    final String expectedDisbursementDateParamName = "expectedDisbursementDate";
    if (command.isChangeInLocalDateParameterNamed(expectedDisbursementDateParamName,
            getExpectedDisbursedOnLocalDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(expectedDisbursementDateParamName);
        actualChanges.put(expectedDisbursementDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(expectedDisbursementDateParamName);
        this.expectedDisbursementDate = newValue.toDate();
        removeFirstDisbursementTransaction();
    }

    final String repaymentsStartingFromDateParamName = "repaymentsStartingFromDate";
    if (command.isChangeInLocalDateParameterNamed(repaymentsStartingFromDateParamName,
            getExpectedFirstRepaymentOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(repaymentsStartingFromDateParamName);
        actualChanges.put(repaymentsStartingFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(repaymentsStartingFromDateParamName);
        if (newValue != null) {
            this.expectedFirstRepaymentOnDate = newValue.toDate();
        } else {
            this.expectedFirstRepaymentOnDate = null;
        }
    }

    final String syncDisbursementParameterName = "syncDisbursementWithMeeting";
    if (command.isChangeInBooleanParameterNamed(syncDisbursementParameterName,
            isSyncDisbursementWithMeeting())) {
        final Boolean valueAsInput = command.booleanObjectValueOfParameterNamed(syncDisbursementParameterName);
        actualChanges.put(syncDisbursementParameterName, valueAsInput);
        this.syncDisbursementWithMeeting = valueAsInput;
    }

    final String interestChargedFromDateParamName = "interestChargedFromDate";
    if (command.isChangeInLocalDateParameterNamed(interestChargedFromDateParamName,
            getInterestChargedFromDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(interestChargedFromDateParamName);
        actualChanges.put(interestChargedFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(interestChargedFromDateParamName);
        if (newValue != null) {
            this.interestChargedFromDate = newValue.toDate();
        } else {
            this.interestChargedFromDate = null;
        }
    }

    // the comparison should be done with the tenant date
    // (DateUtils.getLocalDateOfTenant()) and not the server date (new
    // LocalDate())
    if (getSubmittedOnDate().isAfter(DateUtils.getLocalDateOfTenant())) {
        final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage,
                getSubmittedOnDate());
    }

    if (!(this.client == null)) {
        if (getSubmittedOnDate().isBefore(this.client.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than client's activation date.";
            throw new InvalidLoanStateTransitionException("submittal",
                    "cannot.be.before.client.activation.date", errorMessage, getSubmittedOnDate());
        }
    } else if (!(this.group == null)) {
        if (getSubmittedOnDate().isBefore(this.group.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
            throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date",
                    errorMessage, getSubmittedOnDate());
        }
    }

    if (getSubmittedOnDate().isAfter(getExpectedDisbursedOnLocalDate())) {
        final String errorMessage = "The date on which a loan is submitted cannot be after its expected disbursement date: "
                + getExpectedDisbursedOnLocalDate().toString();
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.after.expected.disbursement.date",
                errorMessage, getSubmittedOnDate(), getExpectedDisbursedOnLocalDate());
    }

    final String chargesParamName = "charges";

    if (isChargesModified) {
        actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges));
        actualChanges.put("recalculateLoanSchedule", true);
    }

    final String collateralParamName = "collateral";
    if (command.parameterExists(collateralParamName)) {

        if (!possiblyModifedLoanCollateralItems.equals(this.collateral)) {
            actualChanges.put(collateralParamName,
                    listOfLoanCollateralData(possiblyModifedLoanCollateralItems));
        }
    }

    final String loanTermFrequencyParamName = "loanTermFrequency";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyParamName, this.termFrequency)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.termFrequency = newValue;
    }

    final String loanTermFrequencyTypeParamName = "loanTermFrequencyType";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyTypeParamName, this.termPeriodFrequencyType)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyTypeParamName);
        final PeriodFrequencyType newTermPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
        actualChanges.put(loanTermFrequencyTypeParamName, newTermPeriodFrequencyType.getValue());
        this.termPeriodFrequencyType = newValue;
    }

    final String principalParamName = "principal";
    if (command.isChangeInBigDecimalParameterNamed(principalParamName, this.approvedPrincipal)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
        this.approvedPrincipal = newValue;
    }

    if (command.isChangeInBigDecimalParameterNamed(principalParamName, this.proposedPrincipal)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
        this.proposedPrincipal = newValue;
    }

    if (loanProduct.isMultiDisburseLoan()) {
        updateDisbursementDetails(command, actualChanges);
        if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName,
                this.maxOutstandingLoanBalance)) {
            this.maxOutstandingLoanBalance = command
                    .bigDecimalValueOfParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName);
        }
        final JsonArray disbursementDataArray = command
                .arrayOfParameterNamed(LoanApiConstants.disbursementDataParameterName);

        if (disbursementDataArray == null || disbursementDataArray.size() == 0) {
            final String errorMessage = "For this loan product, disbursement details must be provided";
            throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName,
                    errorMessage);
        }
        if (disbursementDataArray.size() > loanProduct.maxTrancheCount()) {
            final String errorMessage = "Number of tranche shouldn't be greter than "
                    + loanProduct.maxTrancheCount();
            throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName,
                    errorMessage, loanProduct.maxTrancheCount(), disbursementDetails.size());
        }
    } else {
        this.disbursementDetails.clear();
    }

    if (loanProduct.isMultiDisburseLoan() || loanProduct.canDefineInstallmentAmount()) {
        if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.emiAmountParameterName,
                this.fixedEmiAmount)) {
            this.fixedEmiAmount = command
                    .bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
            actualChanges.put(LoanApiConstants.emiAmountParameterName, this.fixedEmiAmount);
            actualChanges.put("recalculateLoanSchedule", true);
        }
    } else {
        this.fixedEmiAmount = null;
    }

    return actualChanges;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

public Map<String, Object> loanApplicationModification(final JsonCommand command,
        final Set<LoanCharge> possiblyModifedLoanCharges,
        final Set<LoanCollateral> possiblyModifedLoanCollateralItems, final AprCalculator aprCalculator,
        boolean isChargesModified) {

    final Map<String, Object> actualChanges = this.loanRepaymentScheduleDetail
            .updateLoanApplicationAttributes(command, aprCalculator);
    if (!actualChanges.isEmpty()) {
        final boolean recalculateLoanSchedule = !(actualChanges.size() == 1
                && actualChanges.containsKey("inArrearsTolerance"));
        actualChanges.put("recalculateLoanSchedule", recalculateLoanSchedule);
        isChargesModified = true;/*from ww  w . j av a2 s .  co m*/
    }

    final String dateFormatAsInput = command.dateFormat();
    final String localeAsInput = command.locale();

    final String accountNoParamName = "accountNo";
    if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) {
        final String newValue = command.stringValueOfParameterNamed(accountNoParamName);
        actualChanges.put(accountNoParamName, newValue);
        this.accountNumber = StringUtils.defaultIfEmpty(newValue, null);
    }

    final String createSiAtDisbursementParameterName = "createStandingInstructionAtDisbursement";
    if (command.isChangeInBooleanParameterNamed(createSiAtDisbursementParameterName,
            shouldCreateStandingInstructionAtDisbursement())) {
        final Boolean valueAsInput = command
                .booleanObjectValueOfParameterNamed(createSiAtDisbursementParameterName);
        actualChanges.put(createSiAtDisbursementParameterName, valueAsInput);
        this.createStandingInstructionAtDisbursement = valueAsInput;
    }

    final String externalIdParamName = "externalId";
    if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
        final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.externalId = StringUtils.defaultIfEmpty(newValue, null);
    }

    // add clientId, groupId and loanType changes to actual changes

    final String clientIdParamName = "clientId";
    final Long clientId = this.client == null ? null : this.client.getId();
    if (command.isChangeInLongParameterNamed(clientIdParamName, clientId)) {
        final Long newValue = command.longValueOfParameterNamed(clientIdParamName);
        actualChanges.put(clientIdParamName, newValue);
    }

    // FIXME: AA - We may require separate api command to move loan from one
    // group to another
    final String groupIdParamName = "groupId";
    final Long groupId = this.group == null ? null : this.group.getId();
    if (command.isChangeInLongParameterNamed(groupIdParamName, groupId)) {
        final Long newValue = command.longValueOfParameterNamed(groupIdParamName);
        actualChanges.put(groupIdParamName, newValue);
    }

    final String productIdParamName = "productId";
    if (command.isChangeInLongParameterNamed(productIdParamName, this.loanProduct.getId())) {
        final Long newValue = command.longValueOfParameterNamed(productIdParamName);
        actualChanges.put(productIdParamName, newValue);
        actualChanges.put("recalculateLoanSchedule", true);
    }

    final String isFloatingInterestRateParamName = "isFloatingInterestRate";
    if (command.isChangeInBooleanParameterNamed(isFloatingInterestRateParamName, this.isFloatingInterestRate)) {
        final Boolean newValue = command.booleanObjectValueOfParameterNamed(isFloatingInterestRateParamName);
        actualChanges.put(isFloatingInterestRateParamName, newValue);
        this.isFloatingInterestRate = newValue;
    }

    final String interestRateDifferentialParamName = "interestRateDifferential";
    if (command.isChangeInBigDecimalParameterNamed(interestRateDifferentialParamName,
            this.interestRateDifferential)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateDifferentialParamName);
        actualChanges.put(interestRateDifferentialParamName, newValue);
        this.interestRateDifferential = newValue;
    }

    Long existingFundId = null;
    if (this.fund != null) {
        existingFundId = this.fund.getId();
    }
    final String fundIdParamName = "fundId";
    if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) {
        final Long newValue = command.longValueOfParameterNamed(fundIdParamName);
        actualChanges.put(fundIdParamName, newValue);
    }

    Long existingLoanOfficerId = null;
    if (this.loanOfficer != null) {
        existingLoanOfficerId = this.loanOfficer.getId();
    }
    final String loanOfficerIdParamName = "loanOfficerId";
    if (command.isChangeInLongParameterNamed(loanOfficerIdParamName, existingLoanOfficerId)) {
        final Long newValue = command.longValueOfParameterNamed(loanOfficerIdParamName);
        actualChanges.put(loanOfficerIdParamName, newValue);
    }

    Long existingLoanPurposeId = null;
    if (this.loanPurpose != null) {
        existingLoanPurposeId = this.loanPurpose.getId();
    }
    final String loanPurposeIdParamName = "loanPurposeId";
    if (command.isChangeInLongParameterNamed(loanPurposeIdParamName, existingLoanPurposeId)) {
        final Long newValue = command.longValueOfParameterNamed(loanPurposeIdParamName);
        actualChanges.put(loanPurposeIdParamName, newValue);
    }

    final String strategyIdParamName = "transactionProcessingStrategyId";
    if (command.isChangeInLongParameterNamed(strategyIdParamName, this.transactionProcessingStrategy.getId())) {
        final Long newValue = command.longValueOfParameterNamed(strategyIdParamName);
        actualChanges.put(strategyIdParamName, newValue);
    }

    final String submittedOnDateParamName = "submittedOnDate";
    if (command.isChangeInLocalDateParameterNamed(submittedOnDateParamName, getSubmittedOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(submittedOnDateParamName);
        actualChanges.put(submittedOnDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);

        final LocalDate newValue = command.localDateValueOfParameterNamed(submittedOnDateParamName);
        this.submittedOnDate = newValue.toDate();
    }

    final String expectedDisbursementDateParamName = "expectedDisbursementDate";
    if (command.isChangeInLocalDateParameterNamed(expectedDisbursementDateParamName,
            getExpectedDisbursedOnLocalDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(expectedDisbursementDateParamName);
        actualChanges.put(expectedDisbursementDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(expectedDisbursementDateParamName);
        this.expectedDisbursementDate = newValue.toDate();
        removeFirstDisbursementTransaction();
    }

    final String repaymentsStartingFromDateParamName = "repaymentsStartingFromDate";
    if (command.isChangeInLocalDateParameterNamed(repaymentsStartingFromDateParamName,
            getExpectedFirstRepaymentOnDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(repaymentsStartingFromDateParamName);
        actualChanges.put(repaymentsStartingFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(repaymentsStartingFromDateParamName);
        if (newValue != null) {
            this.expectedFirstRepaymentOnDate = newValue.toDate();
        } else {
            this.expectedFirstRepaymentOnDate = null;
        }
    }

    final String syncDisbursementParameterName = "syncDisbursementWithMeeting";
    if (command.isChangeInBooleanParameterNamed(syncDisbursementParameterName,
            isSyncDisbursementWithMeeting())) {
        final Boolean valueAsInput = command.booleanObjectValueOfParameterNamed(syncDisbursementParameterName);
        actualChanges.put(syncDisbursementParameterName, valueAsInput);
        this.syncDisbursementWithMeeting = valueAsInput;
    }

    final String interestChargedFromDateParamName = "interestChargedFromDate";
    if (command.isChangeInLocalDateParameterNamed(interestChargedFromDateParamName,
            getInterestChargedFromDate())) {
        final String valueAsInput = command.stringValueOfParameterNamed(interestChargedFromDateParamName);
        actualChanges.put(interestChargedFromDateParamName, valueAsInput);
        actualChanges.put("dateFormat", dateFormatAsInput);
        actualChanges.put("locale", localeAsInput);
        actualChanges.put("recalculateLoanSchedule", true);

        final LocalDate newValue = command.localDateValueOfParameterNamed(interestChargedFromDateParamName);
        if (newValue != null) {
            this.interestChargedFromDate = newValue.toDate();
        } else {
            this.interestChargedFromDate = null;
        }
    }

    // the comparison should be done with the tenant date
    // (DateUtils.getLocalDateOfTenant()) and not the server date (new
    // LocalDate())
    if (getSubmittedOnDate().isAfter(DateUtils.getLocalDateOfTenant())) {
        final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage,
                getSubmittedOnDate());
    }

    if (!(this.client == null)) {
        if (getSubmittedOnDate().isBefore(this.client.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than client's activation date.";
            throw new InvalidLoanStateTransitionException("submittal",
                    "cannot.be.before.client.activation.date", errorMessage, getSubmittedOnDate());
        }
    } else if (!(this.group == null)) {
        if (getSubmittedOnDate().isBefore(this.group.getActivationLocalDate())) {
            final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
            throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date",
                    errorMessage, getSubmittedOnDate());
        }
    }

    if (getSubmittedOnDate().isAfter(getExpectedDisbursedOnLocalDate())) {
        final String errorMessage = "The date on which a loan is submitted cannot be after its expected disbursement date: "
                + getExpectedDisbursedOnLocalDate().toString();
        throw new InvalidLoanStateTransitionException("submittal", "cannot.be.after.expected.disbursement.date",
                errorMessage, getSubmittedOnDate(), getExpectedDisbursedOnLocalDate());
    }

    final String chargesParamName = "charges";

    if (isChargesModified) {
        actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges));
        actualChanges.put("recalculateLoanSchedule", true);
    }

    final String collateralParamName = "collateral";
    if (command.parameterExists(collateralParamName)) {

        if (!possiblyModifedLoanCollateralItems.equals(this.collateral)) {
            actualChanges.put(collateralParamName,
                    listOfLoanCollateralData(possiblyModifedLoanCollateralItems));
        }
    }

    final String loanTermFrequencyParamName = "loanTermFrequency";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyParamName, this.termFrequency)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyParamName);
        actualChanges.put(externalIdParamName, newValue);
        this.termFrequency = newValue;
    }

    final String loanTermFrequencyTypeParamName = "loanTermFrequencyType";
    if (command.isChangeInIntegerParameterNamed(loanTermFrequencyTypeParamName, this.termPeriodFrequencyType)) {
        final Integer newValue = command.integerValueOfParameterNamed(loanTermFrequencyTypeParamName);
        final PeriodFrequencyType newTermPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
        actualChanges.put(loanTermFrequencyTypeParamName, newTermPeriodFrequencyType.getValue());
        this.termPeriodFrequencyType = newValue;
    }

    final String principalParamName = "principal";
    if (command.isChangeInBigDecimalParameterNamed(principalParamName, this.approvedPrincipal)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
        this.approvedPrincipal = newValue;
    }

    if (command.isChangeInBigDecimalParameterNamed(principalParamName, this.proposedPrincipal)) {
        final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
        this.proposedPrincipal = newValue;
    }

    if (loanProduct.isMultiDisburseLoan()) {
        updateDisbursementDetails(command, actualChanges);
        if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName,
                this.maxOutstandingLoanBalance)) {
            this.maxOutstandingLoanBalance = command
                    .bigDecimalValueOfParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName);
        }
        final JsonArray disbursementDataArray = command
                .arrayOfParameterNamed(LoanApiConstants.disbursementDataParameterName);

        if (disbursementDataArray == null || disbursementDataArray.size() == 0) {
            final String errorMessage = "For this loan product, disbursement details must be provided";
            throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName,
                    errorMessage);
        }
        if (disbursementDataArray.size() > loanProduct.maxTrancheCount()) {
            final String errorMessage = "Number of tranche shouldn't be greter than "
                    + loanProduct.maxTrancheCount();
            throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName,
                    errorMessage, loanProduct.maxTrancheCount(), disbursementDetails.size());
        }
    } else {
        this.disbursementDetails.clear();
    }

    if (loanProduct.isMultiDisburseLoan() || loanProduct.canDefineInstallmentAmount()) {
        if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.emiAmountParameterName,
                this.fixedEmiAmount)) {
            this.fixedEmiAmount = command
                    .bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
            actualChanges.put(LoanApiConstants.emiAmountParameterName, this.fixedEmiAmount);
            actualChanges.put("recalculateLoanSchedule", true);
        }
    } else {
        this.fixedEmiAmount = null;
    }

    return actualChanges;
}