<commit_before>/*
 * Copyright 2006-2008 The Kuali Foundation
 * 
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.opensource.org/licenses/ecl1.php
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.kra.committee.rules;

import java.sql.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.kuali.kra.committee.bo.CommitteeMembership;
import org.kuali.kra.committee.bo.CommitteeMembershipRole;
import org.kuali.kra.committee.document.CommitteeDocument;
import org.kuali.kra.committee.rule.AddCommitteeMembershipRoleRule;
import org.kuali.kra.committee.rule.AddCommitteeMembershipRule;
import org.kuali.kra.committee.rule.event.AddCommitteeMembershipEvent;
import org.kuali.kra.committee.rule.event.AddCommitteeMembershipRoleEvent;
import org.kuali.kra.infrastructure.KeyConstants;
import org.kuali.kra.rules.ResearchDocumentRuleBase;

/**
 * 
 * This class contains the rules to validate a <code>{@link CommitteeMembership}</code>
 * 
 * @author Kuali Research Administration Team (<EMAIL>)
 */
public class CommitteeMembershipRule extends ResearchDocumentRuleBase 
                                     implements AddCommitteeMembershipRule,
                                                AddCommitteeMembershipRoleRule {

    private final String PROPERTY_NAME_PERSON_NAME = "membershipHelper.newCommitteeMembership.personName";
    private final String PROPERTY_NAME_NEW_ROLE_PREFIX = "membershipRolesHelper.newCommitteeMembershipRoles[";
    private final String PROPERTY_NAME_ROLE_CODE = "].membershipRoleCode";
    private final String PROPERTY_NAME_ROLE_START_DATE = "].startDate";
    private final String PROPERTY_NAME_ROLE_END_DATE = "].endDate";
        
    /**
     * Process the validation rules for an <code>{@link AddCommitteeMembershipEvent}</code>.
     * 
     * @param addProtocolParticipantEvent
     * @return <code>true</code> if all validation rules are passed, <code>false</code> otherwise
     */
    public boolean processAddCommitteeMembershipBusinessRules(AddCommitteeMembershipEvent addCommitteeMembershipEvent) {
        boolean isValid = true;
        
        CommitteeMembership committeeMembership = addCommitteeMembershipEvent.getCommitteeMembership();
        
        if ((StringUtils.isEmpty(committeeMembership.getPersonId())) && (committeeMembership.getRolodexId() == null)) { 
            isValid = false;
            reportError(PROPERTY_NAME_PERSON_NAME, KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_PERSON_NOT_SPECIFIED);
        } 
        
        return isValid;
    }
    
    /**
     * Process the validation rules for an <code>{@link addCommitteeMembershipRoleEvent}</code>.
     * 
     * @param addCommitteeMembershipRoleEvent
     * @return <code>true</code> if all validation rules are passed, <code>false</code> otherwise
     */
    public boolean processAddCommitteeMembershipRoleBusinessRules(AddCommitteeMembershipRoleEvent addCommitteeMembershipRoleEvent) {
        boolean isValid = true;
        
        CommitteeMembershipRole membershipRole = addCommitteeMembershipRoleEvent.getCommitteeMembershipRole();

        int membershipIndex = addCommitteeMembershipRoleEvent.getMembershipIndex();
        
        CommitteeDocument committeeDocument = (CommitteeDocument) addCommitteeMembershipRoleEvent.getDocument();
        CommitteeMembership committeeMembership = committeeDocument.getCommittee().getCommitteeMemberships().get(membershipIndex);
        List<CommitteeMembershipRole> membershipRoles = committeeMembership.getMembershipRoles();

        // Verify role code
        if (StringUtils.isBlank(membershipRole.getMembershipRoleCode())) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_CODE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_NOT_SPECIFIED);
        }
        
        // Verify role start date
        if (membershipRole.getStartDate() == null) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_START_DATE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_START_DATE_NOT_SPECIFIED);
        }
        if (hasDateOutsideCommitteeMembershipTerm(committeeMembership, membershipRole.getStartDate())) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_START_DATE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_START_DATE_OUTSIDE_TERM);
        }

        // Verify role end date
        if (membershipRole.getEndDate() == null) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_END_DATE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_NOT_SPECIFIED);
        }
        if (membershipRole.getStartDate() != null && membershipRole.getEndDate() != null 
                && membershipRole.getEndDate().before(membershipRole.getStartDate())) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_END_DATE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_BEFORE_ROLE_START_DATE);
        }
        if (hasDateOutsideCommitteeMembershipTerm(committeeMembership, membershipRole.getEndDate())) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_END_DATE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_OUTSIDE_TERM);
        }
        
        // To keep the errors more comprehensible the role overlap check is done after other errors are resolved
        if (isValid && hasRoleOverlap(membershipRole, membershipRoles)) {
            isValid = false;
            reportError(PROPERTY_NAME_NEW_ROLE_PREFIX + membershipIndex + PROPERTY_NAME_ROLE_CODE, 
                    KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_DUPLICATE);
            
        }
        
        return isValid;
    }
    
    /**
     * Check if the date is outside the committee membership term.
     * If any of the date are null the method returns false.
     * 
     * @param committeeMembership - the committeeMembership whose term we are comparing against
     * @param date - the date to be checked
     * @return <code>true</code> if the date is outside the committee membership term, <code>false</code> otherwise
     */
    private boolean hasDateOutsideCommitteeMembershipTerm(CommitteeMembership committeeMembership, Date date) {
        boolean isOutside = false;
        if ((committeeMembership.getTermStartDate() != null) && (committeeMembership.getTermEndDate() != null) && (date != null)) {
            if (date.before(committeeMembership.getTermStartDate()) || date.after(committeeMembership.getTermEndDate())) {
                isOutside = true;
            }
        }<commit_msg>KCIRB-65 Change membershipIndex related String concatenation to use String.format()<commit_after>/*
 * Copyright 2006-2008 The Kuali Foundation
 * 
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.opensource.org/licenses/ecl1.php
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.kra.committee.rules;

import java.sql.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.kuali.kra.committee.bo.CommitteeMembership;
import org.kuali.kra.committee.bo.CommitteeMembershipRole;
import org.kuali.kra.committee.document.CommitteeDocument;
import org.kuali.kra.committee.rule.AddCommitteeMembershipRoleRule;
import org.kuali.kra.committee.rule.AddCommitteeMembershipRule;
import org.kuali.kra.committee.rule.event.AddCommitteeMembershipEvent;
import org.kuali.kra.committee.rule.event.AddCommitteeMembershipRoleEvent;
import org.kuali.kra.infrastructure.KeyConstants;
import org.kuali.kra.rules.ResearchDocumentRuleBase;

/**
 * 
 * This class contains the rules to validate a <code>{@link CommitteeMembership}</code>
 * 
 * @author Kuali Research Administration Team (<EMAIL>)
 */
public class CommitteeMembershipRule extends ResearchDocumentRuleBase 
                                     implements AddCommitteeMembershipRule,
                                                AddCommitteeMembershipRoleRule {

    private final String PROPERTY_NAME_PERSON_NAME = "membershipHelper.newCommitteeMembership.personName";
    private final String PROPERTY_NAME_ROLE_CODE = "membershipRolesHelper.newCommitteeMembershipRoles[%1$s].membershipRoleCode";
    private final String PROPERTY_NAME_ROLE_START_DATE = "membershipRolesHelper.newCommitteeMembershipRoles[%1$s].membershipRoleCode"; 
    private final String PROPERTY_NAME_ROLE_END_DATE = "membershipRolesHelper.newCommitteeMembershipRoles[%1$s].membershipRoleCode"; 
                    
    /**
     * Process the validation rules for an <code>{@link AddCommitteeMembershipEvent}</code>.
     * 
     * @param addProtocolParticipantEvent
     * @return <code>true</code> if all validation rules are passed, <code>false</code> otherwise
     */
    public boolean processAddCommitteeMembershipBusinessRules(AddCommitteeMembershipEvent addCommitteeMembershipEvent) {
        boolean isValid = true;
        
        CommitteeMembership committeeMembership = addCommitteeMembershipEvent.getCommitteeMembership();
        
        if ((StringUtils.isEmpty(committeeMembership.getPersonId())) && (committeeMembership.getRolodexId() == null)) { 
            isValid = false;
            reportError(PROPERTY_NAME_PERSON_NAME, KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_PERSON_NOT_SPECIFIED);
        } 
        
        return isValid;
    }
    
    /**
     * Process the validation rules for an <code>{@link addCommitteeMembershipRoleEvent}</code>.
     * 
     * @param addCommitteeMembershipRoleEvent
     * @return <code>true</code> if all validation rules are passed, <code>false</code> otherwise
     */
    public boolean processAddCommitteeMembershipRoleBusinessRules(AddCommitteeMembershipRoleEvent addCommitteeMembershipRoleEvent) {
        boolean isValid = true;
        
        CommitteeMembershipRole membershipRole = addCommitteeMembershipRoleEvent.getCommitteeMembershipRole();

        int membershipIndex = addCommitteeMembershipRoleEvent.getMembershipIndex();
        
        CommitteeDocument committeeDocument = (CommitteeDocument) addCommitteeMembershipRoleEvent.getDocument();
        CommitteeMembership committeeMembership = committeeDocument.getCommittee().getCommitteeMemberships().get(membershipIndex);
        List<CommitteeMembershipRole> membershipRoles = committeeMembership.getMembershipRoles();

        // Verify role code
        if (StringUtils.isBlank(membershipRole.getMembershipRoleCode())) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_CODE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_NOT_SPECIFIED);
        }
        
        // Verify role start date
        if (membershipRole.getStartDate() == null) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_START_DATE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_START_DATE_NOT_SPECIFIED);
        }
        if (hasDateOutsideCommitteeMembershipTerm(committeeMembership, membershipRole.getStartDate())) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_START_DATE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_START_DATE_OUTSIDE_TERM);
        }

        // Verify role end date
        if (membershipRole.getEndDate() == null) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_END_DATE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_NOT_SPECIFIED);
        }
        if (membershipRole.getStartDate() != null && membershipRole.getEndDate() != null 
                && membershipRole.getEndDate().before(membershipRole.getStartDate())) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_END_DATE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_BEFORE_ROLE_START_DATE);
        }
        if (hasDateOutsideCommitteeMembershipTerm(committeeMembership, membershipRole.getEndDate())) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_END_DATE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_END_DATE_OUTSIDE_TERM);
        }
        
        // To keep the errors more comprehensible the role overlap check is done after other errors are resolved
        if (isValid && hasRoleOverlap(membershipRole, membershipRoles)) {
            isValid = false;
            reportError(String.format(PROPERTY_NAME_ROLE_CODE, membershipIndex), KeyConstants.ERROR_COMMITTEE_MEMBERSHIP_ROLE_DUPLICATE);
        }
        
        return isValid;
    }
    
    /**
     * Check if the date is outside the committee membership term.
     * If any of the date are null the method returns false.
     * 
     * @param committeeMembership - the committeeMembership whose term we are comparing against
     * @param date - the date to be checked
     * @return <code>true</code> if the date is outside the committee membership term, <code>false</code> otherwise
     */
    private boolean hasDateOutsideCommitteeMembershipTerm(CommitteeMembership committeeMembership, Date date) {
        boolean isOutside = false;
        if ((committeeMembership.getTermStartDate() != null) && (committeeMembership.getTermEndDate() != null) && (date != null)) {
            if (date.before(committeeMembership.getTermStartDate()) || date.after(committeeMembership.getTermEndDate())) {
                isOutside = true;
            }
        }
{'fraction_non_alphanumeric': 0.07624753216692763, 'fraction_numerical': 0.0018381101504527197, 'mean_word_length': 3.526964560862866, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6722243', 'n_tokens_mistral': 4073, 'n_tokens_neox': 3969, 'n_words': 818}