org.openregistry.core.repository.jpa.JpaPersonRepository.java Source code

Java tutorial

Introduction

Here is the source code for org.openregistry.core.repository.jpa.JpaPersonRepository.java

Source

/**
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig 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:
 *
 * 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.openregistry.core.repository.jpa;

import org.hibernate.loader.custom.Return;
import org.openregistry.core.domain.*;
import org.openregistry.core.domain.jpa.*;
import org.openregistry.core.domain.jpa.sor.*;
import org.openregistry.core.domain.sor.*;
import org.openregistry.core.repository.*;
import org.openregistry.core.service.*;
import org.springframework.stereotype.*;
import org.springframework.util.StringUtils;

import javax.persistence.*;
import javax.persistence.criteria.*;
import java.util.*;

/**
 * Person repository implementation built on top of JPA.
 *
 * @author Dmitriy Kopylenko
 * @author Scott Battaglia
 * @version $Revision$ $Date$
 * @since 1.0.0
 */
@Repository(value = "personRepository")
public class JpaPersonRepository implements PersonRepository {

    @PersistenceContext(unitName = "OpenRegistryPersistence")
    private EntityManager entityManager;

    private final static int MAX_QUERY_LIMIT = 1000;

    public Person findByInternalId(final Long id) throws RepositoryAccessException {
        return this.entityManager.find(JpaPersonImpl.class, id);
    }

    public Person fetchCompleteCalculatedPerson(Long id) {
        return (Person) this.entityManager.createQuery("Select p from person "
                + " p left join fetch p.identifiers i left join fetch i.type left join fetch p.names left join fetch p.roles r left join fetch p.disclosureSettings d left join fetch r.urls  left join fetch r.emailAddresses  "
                + "left join fetch r.phones left join fetch r.addresses left join fetch r.organizationalUnit left join fetch d.addressDisclosureSettings "
                + "  left join fetch d.emailDisclosureSettings left join fetch d.phoneDisclosureSettings left join fetch d.urlDisclosureSettings  where p.id = :id")
                .setParameter("id", id.longValue()).getSingleResult();

    }

    public SorPerson findSorByInternalId(final Long id) throws RepositoryAccessException {
        return this.entityManager.find(JpaSorPersonImpl.class, id);
    }

    public Person findByIdentifier(final String identifierType, final String identifierValue)
            throws RepositoryAccessException {
        return (Person) this.entityManager.createQuery(
                "Select p from person p join p.identifiers i join i.type t where t.name = :name and i.value = :value")
                .setParameter("name", identifierType).setParameter("value", identifierValue).getSingleResult();
    }

    @Override
    public List<Person> findByUnknownIdentifier(final String identifierValue) throws RepositoryAccessException {
        final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();

        final CriteriaQuery<JpaPersonImpl> c = criteriaBuilder.createQuery(JpaPersonImpl.class);
        final Root<JpaPersonImpl> person = c.from(JpaPersonImpl.class);
        final Join<JpaPersonImpl, JpaIdentifierImpl> identifier = person.join(JpaPersonImpl_.identifiers);

        c.select(person).distinct(true)
                .where(criteriaBuilder.like(identifier.get(JpaIdentifierImpl_.value), identifierValue + "%"));

        final List<JpaPersonImpl> persons = this.entityManager.createQuery(c).getResultList();

        return new ArrayList<Person>(persons);
    }

    public SorPerson findByPersonIdAndSorIdentifier(final Long personId, final String sorSource) {
        return (SorPerson) this.entityManager
                .createQuery("Select s from sorPerson s where s.sourceSor = :sorSource and s.personId = :personId")
                .setParameter("sorSource", sorSource).setParameter("personId", personId).getSingleResult();
    }

    public SorPerson findSorBySSN(final String ssn) {
        //It will be more than one person if the same person is coming from more than one resources
        List sorPersons = this.entityManager.createQuery("Select s from sorPerson s where s.ssn = :ssn")
                .setParameter("ssn", ssn).getResultList();
        if (sorPersons.size() > 0)
            return (SorPerson) sorPersons.get(0);
        return null;
    }

    public List<Person> searchByCriteria(final SearchCriteria searchCriteria) throws RepositoryAccessException {
        final String givenName = searchCriteria.getGivenName();
        final String familyName = searchCriteria.getFamilyName();
        final Date birthDate = searchCriteria.getDateOfBirth();
        final String searchCriteriaName = searchCriteria.getName();

        // search by role criteria
        final String sponsorNetID = searchCriteria.getSponsorNetID();
        final OrganizationalUnit organizationalUnit = searchCriteria.getOrganizationalUnit();
        final Date roleExpDate = searchCriteria.getRoleExpDate();
        final Type roleType = searchCriteria.getAffiliationType();

        final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();

        final CriteriaQuery<JpaPersonImpl> c = criteriaBuilder.createQuery(JpaPersonImpl.class);
        c.distinct(true);
        final Root<JpaPersonImpl> person = c.from(JpaPersonImpl.class);
        final Join<JpaPersonImpl, JpaNameImpl> name = person.join(JpaPersonImpl_.names);
        final Join<JpaPersonImpl, JpaRoleImpl> role = person.join(JpaPersonImpl_.roles);

        //        person.fetch(JpaPersonImpl_.names);
        //        person.fetch(JpaPersonImpl_.roles);
        //        person.fetch(JpaPersonImpl_.identifiers);

        final Predicate pBirthDate;
        if (birthDate != null) {
            pBirthDate = criteriaBuilder.equal(person.get(JpaPersonImpl_.dateOfBirth), birthDate);
        } else {
            pBirthDate = null;
        }

        Predicate combined = null;

        if (StringUtils.hasText(givenName) && StringUtils.hasText(familyName)) {
            //          final Predicate pGivenName = criteriaBuilder.equal(name.get(JpaNameImpl_.given), givenName );
            Expression<String> pattern = criteriaBuilder.literal((String) givenName + "%");
            final Predicate pGivenName = criteriaBuilder.like(name.get(JpaNameImpl_.given), pattern);
            final Predicate pFamilyName = criteriaBuilder.equal(name.get(JpaNameImpl_.family), familyName);

            combined = criteriaBuilder.and(pGivenName, pFamilyName);
        } else if (StringUtils.hasText(givenName)) {
            combined = criteriaBuilder.equal(name.get(JpaNameImpl_.given), givenName);
        } else if (StringUtils.hasText(familyName)) {
            combined = criteriaBuilder.equal(name.get(JpaNameImpl_.family), familyName);
        } else if (StringUtils.hasText(searchCriteriaName)) {
            final Predicate pGivenName = criteriaBuilder.equal(name.get(JpaNameImpl_.given), searchCriteriaName);
            final Predicate pFamilyName = criteriaBuilder.equal(name.get(JpaNameImpl_.family), searchCriteriaName);
            combined = criteriaBuilder.or(pGivenName, pFamilyName);
        }

        Predicate pRoleCombined = null;

        if (roleType != null) {
            //final Join<JpaPersonImpl,JpaRoleImpl> role = person.join(JpaPersonImpl_.roles);
            //final Join<JpaPersonImpl,JpaRoleImpl> role = name.join(JpaPersonImpl_.roles);
            pRoleCombined = criteriaBuilder.equal(role.get(JpaRoleImpl_.affiliationType), roleType);
        }

        if (organizationalUnit != null && StringUtils.hasText(organizationalUnit.getName())) {
            Predicate orgUnitP = criteriaBuilder.equal(role.get(JpaRoleImpl_.organizationalUnit),
                    organizationalUnit);
            if (pRoleCombined != null)
                pRoleCombined = criteriaBuilder.and(pRoleCombined, orgUnitP);
            else
                pRoleCombined = orgUnitP;
            //pRoleCombined = criteriaBuilder.and(pRoleCombined, orgUnitP);
        }

        if (StringUtils.hasText(sponsorNetID)) {
            Person person1 = findByIdentifier(Type.IdentifierTypes.NETID.name(), sponsorNetID);
            if (person1 != null) {
                Predicate sponsorP = criteriaBuilder.equal(role.get(JpaRoleImpl_.sponsorId), person1.getId());
                if (pRoleCombined != null)
                    pRoleCombined = criteriaBuilder.and(pRoleCombined, sponsorP);
                else
                    pRoleCombined = sponsorP;
            } else {
                pRoleCombined = criteriaBuilder.or();
            }

        }
        if (roleExpDate != null) {
            Predicate expDateP = criteriaBuilder.between(role.get(JpaRoleImpl_.end), new Date(), roleExpDate);
            if (pRoleCombined != null)
                pRoleCombined = criteriaBuilder.and(pRoleCombined, expDateP);
            else
                pRoleCombined = expDateP;
        }

        Predicate pComplete = criteriaBuilder.and();

        if (pBirthDate != null)
            pComplete = criteriaBuilder.and(pComplete, pBirthDate);
        if (combined != null)
            pComplete = criteriaBuilder.and(pComplete, combined);
        if (pRoleCombined != null)
            pComplete = criteriaBuilder.and(pComplete, pRoleCombined);

        c.select(person).where(pComplete);

        //        if (pBirthDate != null && combined != null) {
        //            c.select(person).where(criteriaBuilder.and(pBirthDate, combined));
        //        } else if (pBirthDate != null) {
        //            c.select(person).where(pBirthDate);
        //        } else {
        //            c.select(person).where(combined);
        //        }

        final List<JpaPersonImpl> persons = this.entityManager.createQuery(c).setMaxResults(MAX_QUERY_LIMIT)
                .getResultList();

        return new ArrayList<Person>(persons);
    }

    public List<Person> findByFamilyName(final String family) throws RepositoryAccessException {
        return this.entityManager
                .createQuery("SELECT distinct p FROM person p JOIN  p.names n WHERE n.family = :name")
                .setParameter("name", family).getResultList();
    }

    public List<Person> findByFamilyComparisonValue(final String familyComparisonValue)
            throws RepositoryAccessException {
        return this.entityManager.createQuery(
                "SELECT distinct p FROM person p JOIN  p.names n WHERE n.familyComparisonValue = :comparisonValue")
                .setParameter("comparisonValue", familyComparisonValue).getResultList();
    }

    public Person savePerson(final Person person) throws RepositoryAccessException {
        Person p = this.entityManager.merge(person);
        //the only solution of insert before delete problem
        this.entityManager.flush();
        return p;
    }

    public SorPerson saveSorPerson(final SorPerson person) throws RepositoryAccessException {
        return this.entityManager.merge(person);
    }

    public void deleteSorRole(final SorPerson person, final SorRole role) {
        SorRole sorRoleToDelete = this.entityManager.getReference(role.getClass(), role.getId());
        this.entityManager.remove(sorRoleToDelete);
        saveSorPerson(person);
    }

    public void updateRole(final Person person, final Role role) {
        this.entityManager.merge(person);
    }

    public SorRole saveSorRole(final SorRole role) throws RepositoryAccessException {
        return this.entityManager.merge(role);
    }

    public SorPerson findBySorIdentifierAndSource(final String sorSource, final String sorId) {
        return (SorPerson) this.entityManager
                .createQuery("select s from sorPerson s where s.sourceSor = :sorSource and s.sorId = :sorId")
                .setParameter("sorSource", sorSource).setParameter("sorId", sorId).getSingleResult();
    }

    public void deleteSorPerson(final SorPerson sorPerson) {
        SorPerson sorPersonToDelete = this.entityManager.getReference(sorPerson.getClass(), sorPerson.getId());
        this.entityManager.remove(sorPersonToDelete);
    }

    /**
     * Returns the SoR records for a particular person.
     *
     * @param person the person
     * @return a list of sorPerson records.
     */
    public List<SorPerson> getSoRRecordsForPerson(final Person person) {
        return (List<SorPerson>) this.entityManager
                .createQuery("select s from sorPerson s where s.personId = :personId")
                .setParameter("personId", person.getId()).getResultList();
    }

    public Number getCountOfSoRRecordsForPerson(final Person person) {
        return (Number) this.entityManager
                .createQuery("select count(s) from sorPerson s where s.personId = :personId")
                .setParameter("personId", person.getId()).getSingleResult();
    }

    public void deletePerson(final Person person) {
        this.entityManager.remove(person);
        this.entityManager.flush();
    }

    public List<Person> findByEmailAddressAndPhoneNumber(final String email, final String countryCode,
            final String areaCode, final String number, final String extension) {
        return (List<Person>) this.entityManager.createQuery(
                "select p from person p join p.roles r, IN(r.emailAddresses) e, IN(r.phones) ph where e.address = :email and ph.countryCode = :countryCode and ph.areaCode = :areaCode and ph.number = :number and ph.extension = :extension")
                .setParameter("email", email).setParameter("countryCode", countryCode)
                .setParameter("areaCode", areaCode).setParameter("number", number)
                .setParameter("extension", extension).getResultList();
    }

    /* No extension */
    public List<Person> findByEmailAddressAndPhoneNumber(final String email, final String countryCode,
            final String areaCode, final String number) {
        return (List<Person>) this.entityManager.createQuery(
                "select p from person p join p.roles r, IN(r.emailAddresses) e, IN(r.phones) ph where e.address = :email and ph.countryCode = :countryCode and ph.areaCode = :areaCode and ph.number = :number")
                .setParameter("email", email).setParameter("countryCode", countryCode)
                .setParameter("areaCode", areaCode).setParameter("number", number).getResultList();
    }

    public List<Person> findByEmailAddress(final String email) {
        return (List<Person>) this.entityManager
                .createQuery(
                        "select p from person p join p.roles r, IN(r.emailAddresses) e where e.address = :email")
                .setParameter("email", email).getResultList();
    }

    public List<Person> findByPhoneNumber(final String countryCode, final String areaCode, final String number,
            final String extension) {
        return (List<Person>) this.entityManager.createQuery(
                "select p from person p join p.roles r, IN(r.phones) ph where ph.countryCode = :countryCode and ph.areaCode = :areaCode and ph.number = :number and ph.extension = :extension")
                .setParameter("countryCode", countryCode).setParameter("areaCode", areaCode)
                .setParameter("number", number).setParameter("extension", extension).getResultList();
    }

    /* No extension */
    public List<Person> findByPhoneNumber(final String countryCode, final String areaCode, final String number) {
        return (List<Person>) this.entityManager.createQuery(
                "select p from person p join p.roles r, IN(r.phones) ph where ph.countryCode = :countryCode and ph.areaCode = :areaCode and ph.number = :number")
                .setParameter("countryCode", countryCode).setParameter("areaCode", areaCode)
                .setParameter("number", number).getResultList();
    }

    /**
     * Expose underlying EntityManager
     * @return EntityManager
     */
    public EntityManager getEntityManager() {
        return entityManager;
    }

    public SorRole getSoRRoleForRole(Role calculatedRole) {
        return (SorRole) this.entityManager.createQuery("select r from sorRole r where r.id =:recordID")
                .setParameter("recordID", calculatedRole.getSorRoleId()).getSingleResult();

    }

    public Role getCalculatedRoleForSorRole(SorRole sorRole) {
        List roles = this.entityManager.createQuery("select r from role r where r.sorRoleId =:sorRecordID")
                .setParameter("sorRecordID", sorRole.getId()).getResultList();
        if (roles.size() > 0) {
            return (Role) roles.get(0);

        }
        return null;
    }
}