org.jasig.ssp.service.external.impl.ExternalPersonServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jasig.ssp.service.external.impl.ExternalPersonServiceImpl.java

Source

/**
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache 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 the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.jasig.ssp.service.external.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jasig.ssp.dao.external.ExternalDataDao;
import org.jasig.ssp.dao.external.ExternalPersonDao;
import org.jasig.ssp.model.Person;
import org.jasig.ssp.model.PersonDemographics;
import org.jasig.ssp.model.PersonStaffDetails;
import org.jasig.ssp.model.external.ExternalPerson;
import org.jasig.ssp.model.reference.Ethnicity;
import org.jasig.ssp.model.reference.Genders;
import org.jasig.ssp.model.reference.MaritalStatus;
import org.jasig.ssp.model.reference.Race;
import org.jasig.ssp.model.reference.StudentType;
import org.jasig.ssp.service.ObjectNotFoundException;
import org.jasig.ssp.service.PersonService;
import org.jasig.ssp.service.PersonStaffDetailsService;
import org.jasig.ssp.service.external.ExternalPersonService;
import org.jasig.ssp.service.reference.ConfigService;
import org.jasig.ssp.service.reference.EthnicityService;
import org.jasig.ssp.service.reference.RaceService;
import org.jasig.ssp.service.reference.MaritalStatusService;
import org.jasig.ssp.service.reference.StudentTypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class ExternalPersonServiceImpl extends AbstractExternalDataService<ExternalPerson>
        implements ExternalPersonService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExternalPersonServiceImpl.class);

    @Autowired
    private transient ExternalPersonDao dao;

    @Autowired
    private transient PersonService personService;

    @Autowired
    private transient PersonStaffDetailsService staffDetailsService;

    @Autowired
    private transient ConfigService configService;

    @Autowired
    private transient MaritalStatusService maritalStatusService;

    @Autowired
    private transient EthnicityService ethnicityService;

    @Autowired
    private transient RaceService raceService;

    @Autowired
    private transient StudentTypeService studentTypeService;

    @Override
    public ExternalPerson getBySchoolId(final String schoolId) throws ObjectNotFoundException {
        return dao.getBySchoolId(schoolId);
    }

    @Override
    public ExternalPerson getByUsername(final String username) throws ObjectNotFoundException {
        return dao.getByUsername(username);
    }

    @Override
    public void updatePersonFromExternalPerson(final Person person) {
        ExternalPerson externalPerson = null;
        final String schoolId = person.getSchoolId();
        final String username = person.getUsername();
        try {
            externalPerson = getBySchoolId(schoolId);
        } catch (ObjectNotFoundException e) {
            try {
                externalPerson = getByUsername(username);
            } catch (ObjectNotFoundException ee) {
                // see below
            }
        }

        if (externalPerson != null) {
            updatePersonFromExternalPerson(person, externalPerson, true);
        } else {
            LOGGER.debug(
                    "Skipping external data sync for " + "person [id: {}] [schoolId: {}] [username: {}]  because "
                            + "there is no corresponding external record under either key.",
                    new Object[] { person.getId(), schoolId, username });
        }

    }

    /**
     * Modifies state of Person for values of ExternalPerson that are different.
     * 
     * @param person
     *            person
     */
    @Override
    public void updatePersonFromExternalPerson(final Person person, final ExternalPerson externalPerson,
            boolean commit) {

        LOGGER.debug("Person and ExternalPerson Sync.  Person school id {}, username {}", person.getSchoolId(),
                person.getUsername());

        // Allow ExternalPerson.schoolId to override that Person field since
        // the ExternalPerson might have been looked up by username rather than
        // schoolId and Person.schoolId is not necessarily trustworthy on 1st
        // time login (https://issues.jasig.org/browse/SSP-1750).
        //
        // Comparison here is intentionally case-sensitive pending
        // https://issues.jasig.org/browse/SSP-1735
        if (person.getSchoolId() == null || (!person.getSchoolId().equals(externalPerson.getSchoolId()))) {
            person.setSchoolId(externalPerson.getSchoolId());
        }

        if (person.getUsername() == null
                || (!person.getUsername().equalsIgnoreCase(externalPerson.getUsername()))) {
            person.setUsername(StringUtils.lowerCase(externalPerson.getUsername()));
        }

        if ((person.getFirstName() == null) || (!person.getFirstName().equals(externalPerson.getFirstName()))) {
            person.setFirstName(externalPerson.getFirstName());
        }

        if ((person.getLastName() == null) || (!person.getLastName().equals(externalPerson.getLastName()))) {
            person.setLastName(externalPerson.getLastName());
        }

        if ((person.getMiddleName() == null) || (!person.getMiddleName().equals(externalPerson.getMiddleName()))) {
            person.setMiddleName(externalPerson.getMiddleName());
        }

        if ((person.getBirthDate() == null) || (!person.getBirthDate().equals(externalPerson.getBirthDate()))) {
            person.setBirthDate(externalPerson.getBirthDate());
        }

        if ((person.getPrimaryEmailAddress() == null)
                || (!person.getPrimaryEmailAddress().equals(externalPerson.getPrimaryEmailAddress()))) {
            person.setPrimaryEmailAddress(externalPerson.getPrimaryEmailAddress());
        }

        if ((person.getAddressLine1() == null)
                || (!person.getAddressLine1().equals(externalPerson.getAddressLine1()))) {
            person.setAddressLine1(externalPerson.getAddressLine1());
        }

        if ((person.getAddressLine2() == null)
                || (!person.getAddressLine2().equals(externalPerson.getAddressLine2()))) {
            person.setAddressLine2(externalPerson.getAddressLine2());
        }

        if ((person.getCity() == null) || (!person.getCity().equals(externalPerson.getCity()))) {
            person.setCity(externalPerson.getCity());
        }

        if ((person.getState() == null) || (!person.getState().equals(externalPerson.getState()))) {
            person.setState(externalPerson.getState());
        }

        if ((person.getZipCode() == null) || (!person.getZipCode().equals(externalPerson.getZipCode()))) {
            person.setZipCode(externalPerson.getZipCode());
        }

        if ((person.getHomePhone() == null) || (!person.getHomePhone().equals(externalPerson.getHomePhone()))) {
            person.setHomePhone(externalPerson.getHomePhone());
        }

        if ((person.getWorkPhone() == null) || (!person.getWorkPhone().equals(externalPerson.getWorkPhone()))) {
            person.setWorkPhone(externalPerson.getWorkPhone());
        }

        if ((person.getCellPhone() == null) || (!person.getCellPhone().equals(externalPerson.getCellPhone()))) {
            person.setCellPhone(externalPerson.getCellPhone());
        }

        if ((person.getPhotoUrl() == null) || (!person.getPhotoUrl().equals(externalPerson.getPhotoUrl()))) {
            person.setPhotoUrl(externalPerson.getPhotoUrl());
        }

        if ((person.getActualStartTerm() == null)
                || (!person.getActualStartTerm().equals(externalPerson.getActualStartTerm()))) {
            person.setActualStartTerm(externalPerson.getActualStartTerm());
        }

        if ((person.getActualStartYear() == null)
                || (!person.getActualStartYear().equals(externalPerson.getActualStartYear()))) {
            person.setActualStartYear(externalPerson.getActualStartYear());
        }

        if ((person.getNonLocalAddress() == null)
                || (!person.getNonLocalAddress().equals(externalPerson.getNonLocalAddress()))) {
            person.setNonLocalAddress(externalPerson.getNonLocalAddress());
        }

        if ((person.getResidencyCounty() == null)
                || (!person.getResidencyCounty().equals(externalPerson.getResidencyCounty()))) {
            person.setResidencyCounty(externalPerson.getResidencyCounty());
        }

        if ((person.getF1Status() == null) || (!person.getF1Status().equals(externalPerson.getF1Status()))) {
            person.setF1Status(externalPerson.getF1Status());
        }

        setCoachForPerson(person, externalPerson.getCoachSchoolId());

        setStudentTypeForPerson(person, externalPerson.getStudentType());

        if ((StringUtils.isBlank(externalPerson.getDepartmentName())
                && StringUtils.isBlank(externalPerson.getOfficeHours())
                && StringUtils.isBlank(externalPerson.getOfficeLocation()))) {
            // this is likely not a staff member
            if (person.getStaffDetails() != null) {
                try {
                    staffDetailsService.delete(person.getStaffDetails().getId());
                } catch (final ObjectNotFoundException e) {
                    LOGGER.info(
                            "Strange that we found a staffDetails object a moment ago, but cannot find it again to delte it.",
                            e);
                }
            }

        } else {
            // this is a staff member, add their details
            if (person.getStaffDetails() == null) {
                person.setStaffDetails(new PersonStaffDetails());
            }

            if ((person.getStaffDetails().getOfficeHours() == null)
                    || (!person.getStaffDetails().getOfficeHours().equals(externalPerson.getOfficeHours()))) {
                person.getStaffDetails().setOfficeHours(externalPerson.getOfficeHours());
            }

            if ((person.getStaffDetails().getOfficeLocation() == null)
                    || (!person.getStaffDetails().getOfficeLocation().equals(externalPerson.getOfficeLocation()))) {
                person.getStaffDetails().setOfficeLocation(externalPerson.getOfficeLocation());
            }

            if ((person.getStaffDetails().getDepartmentName() == null)
                    || (!person.getStaffDetails().getDepartmentName().equals(externalPerson.getDepartmentName()))) {
                person.getStaffDetails().setDepartmentName(externalPerson.getDepartmentName());
            }

        }

        PersonDemographics demographics;
        if (person.getDemographics() == null) {
            demographics = new PersonDemographics();
            person.setDemographics(demographics);
        } else {
            demographics = person.getDemographics();
        }

        //As per SSP-874, how to handle external data overwrites:
        //         Based on jasig-ssp discussions, the rules for the updates to the person_demographics are:
        //         1. Null/Empty/Blank value from external table: over-write (they may be intentionally desiring the existing value overwritten.
        //         2. Valid value from external table that matches entry in reference table: over-write
        //         3. Invalid value from external table that has no matching entry in reference table: don't over-write

        if (StringUtils.isBlank(externalPerson.getMaritalStatus())) {
            demographics.setMaritalStatus(null);
        } else {
            MaritalStatus maritalStatus = maritalStatusService.getByName(externalPerson.getMaritalStatus());
            demographics.setMaritalStatus(maritalStatus == null ? demographics.getMaritalStatus() : maritalStatus);
        }

        if (StringUtils.isBlank(externalPerson.getEthnicity())) {
            demographics.setEthnicity(null);
        } else {
            Ethnicity ethnicity = ethnicityService.getByName(externalPerson.getEthnicity());
            demographics.setEthnicity(ethnicity == null ? demographics.getEthnicity() : ethnicity);
        }

        if (StringUtils.isBlank(externalPerson.getRace())) {
            demographics.setRace(null);
        } else {
            Race race = raceService.getByCode(externalPerson.getRace());
            demographics.setRace(race == null ? demographics.getRace() : race);
        }

        if (StringUtils.isBlank(externalPerson.getGender())) {
            demographics.setGender(null);
        } else {
            try {
                Genders gender = Genders.valueOf(externalPerson.getGender());
                demographics.setGender(gender);
            } catch (IllegalArgumentException e) {
                demographics.setGender(null);
            }
        }

        if (externalPerson.getIsLocal() == null) {
            demographics.setLocal(null);
        } else {
            demographics.setLocal(externalPerson.getIsLocal().equalsIgnoreCase("Y"));
        }

        if (externalPerson.getBalanceOwed() == null) {
            demographics.setBalanceOwed(null);
        } else {
            if ((demographics.getBalanceOwed() == null)
                    || (!demographics.getBalanceOwed().equals(externalPerson.getBalanceOwed()))) {
                demographics.setBalanceOwed(externalPerson.getBalanceOwed());
            }
        }

        try {
            if (commit) {
                personService.save(person);
            }
        } catch (final ObjectNotFoundException e) {
            LOGGER.error("person failed to save", e);
        }

    }

    private void setCoachForPerson(final Person person, final String coachId) {
        if (configService.getByNameNullOrDefaultValue("coachSetFromExternalData").equalsIgnoreCase("false")) {
            LOGGER.debug(
                    "Skipping all coach assignment processing for person "
                            + "schoolId '{}' because that operation has been disabled " + "via configuration.",
                    person.getSchoolId());
            return;
        }

        if (person.getCoach() == null) {
            if (coachId != null && !coachId.trim().isEmpty()) {
                LOGGER.debug("Assigning coach schoolId '{}' to person " + "schoolId '{}'", coachId,
                        person.getSchoolId());
                person.setCoach(getCoach(coachId));
            } // else ignore
        } else {
            if (coachId == null || coachId.trim().isEmpty()) {
                if (configService.getByNameNullOrDefaultValue("coachUnsetFromExternalData")
                        .equalsIgnoreCase("true")) {
                    LOGGER.debug("Deleting coach assignment for person schoolId '{}'", person.getSchoolId());
                    person.setCoach(null);
                } else {
                    LOGGER.debug("Skipping coach assignment deletion for "
                            + "person schoolId '{}' because that operation has "
                            + "been disabled via configuration.", person.getSchoolId());
                }
            } else if (!coachId.equals(person.getCoach().getSchoolId())) {
                Person coach = getCoach(coachId);
                if (coach == null) {
                    // lookup problem already logged
                    LOGGER.debug("Coach with schoolId '{}' does not exist so "
                            + "skipping coach assignment for person schoolId '{}'", person.getSchoolId());
                } else {
                    person.setCoach(coach);
                }
            } // else equals, so ignore
        }
    }

    private Person getCoach(final String coachId) {
        try {
            return personService.getBySchoolId(coachId, true);
        } catch (final ObjectNotFoundException e) {
            LOGGER.warn("Coach referenced in external table not available in system", e);
            return null;
        }
    }

    private void setStudentTypeForPerson(final Person person, final String externStudentType) {
        if (configService.getByNameNullOrDefaultValue("studentTypeSetFromExternalData").equalsIgnoreCase("false")) {
            LOGGER.debug(
                    "Skipping all student type assignment processing for person "
                            + "schoolId '{}' because that operation has been disabled " + "via configuration.",
                    person.getSchoolId());
            return;
        }

        if (person.getStudentType() == null) {
            if (externStudentType != null && !externStudentType.trim().isEmpty()) {
                LOGGER.debug("Assigning student_type '{}' to person " + "schoolId '{}'", externStudentType,
                        person.getSchoolId());
                person.setStudentType(getInternalStudentTypeCode(externStudentType));
            } // else ignore
        } else {
            if (externStudentType == null || externStudentType.trim().isEmpty()) {
                if (configService.getByNameNullOrDefaultValue("studentTypeUnsetFromExternalData")
                        .equalsIgnoreCase("true")) {
                    LOGGER.debug("Deleting student_type assignment for person schoolId '{}'", person.getSchoolId());
                    person.setStudentType(null);
                } else {
                    LOGGER.debug("Skipping student_type assignment deletion for "
                            + "person schoolId '{}' because that operation has "
                            + "been disabled via configuration.", person.getSchoolId());
                }
            } else if (!externStudentType.equals(person.getStudentType().getCode())) {
                StudentType studentType = getInternalStudentTypeCode(externStudentType);
                if (studentType == null) {
                    // lookup problem already logged
                    LOGGER.debug(
                            "Student Type with name '{}' does not exist so "
                                    + "skipping student_type assignment for person schoolId '{}'",
                            externStudentType, person.getSchoolId());
                } else {
                    person.setStudentType(studentType);
                }
            } // else equals, so ignore
        }
    }

    private StudentType getInternalStudentTypeCode(final String studentTypeCode) {
        try {
            return studentTypeService.getByCode(studentTypeCode);
        } catch (final ObjectNotFoundException e) {
            LOGGER.warn("Student_Type " + studentTypeCode + " referenced in external table not "
                    + "available in system. ", e);
            return null;
        }
    }

    @Override
    protected ExternalDataDao<ExternalPerson> getDao() {
        return dao;
    }

    @Override
    public List<String> getAllDepartmentNames() {
        return dao.getAllDepartmentNames();
    }

}