package edu.gatech.i3l.fhir.jpa.dao; import java.util.Calendar; import java.util.Date; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.From; import javax.persistence.criteria.Predicate; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.rest.param.DateRangeParam; import edu.gatech.i3l.fhir.dstu2.entities.PersonComplement; import edu.gatech.i3l.fhir.jpa.entity.IResourceEntity; import edu.gatech.i3l.fhir.jpa.query.AbstractPredicateBuilder; import edu.gatech.i3l.fhir.jpa.query.PredicateBuilder; @Transactional(propagation = Propagation.REQUIRED) public class PatientFhirResourceDao extends BaseFhirResourceDao<Patient> { public PatientFhirResourceDao() { super(); setResourceEntity(PersonComplement.class); setValidateBean(true); } @Override public PredicateBuilder getPredicateBuilder() { return new AbstractPredicateBuilder() { @Override public Predicate translatePredicateString(Class<? extends IResourceEntity> entity, String theParamName, String likeExpression, From<? extends IResourceEntity, ? extends IResourceEntity> from, CriteriaBuilder theBuilder) { Predicate singleCode = null; switch (theParamName) { case Patient.SP_ADDRESS: Predicate lc1 = theBuilder.like(from.get("location").get("address1").as(String.class), likeExpression); Predicate lc2 = theBuilder.like(from.get("location").get("address2").as(String.class), likeExpression); Predicate lc3 = theBuilder.like(from.get("location").get("city").as(String.class), likeExpression); Predicate lc4 = theBuilder.like(from.get("location").get("state").as(String.class), likeExpression); Predicate lc5 = theBuilder.like(from.get("location").get("zipCode").as(String.class), likeExpression); Predicate lc6 = theBuilder.like(from.get("location").get("country").as(String.class), likeExpression); singleCode = theBuilder.or(lc1, lc2, lc3, lc4, lc5, lc6); break; case Patient.SP_GIVEN: Predicate gn1 = theBuilder.like(from.get("givenName1").as(String.class), likeExpression); Predicate gn2 = theBuilder.like(from.get("givenName2").as(String.class), likeExpression); singleCode = theBuilder.or(gn1, gn2); break; case Patient.SP_FAMILY: singleCode = theBuilder.like(from.get("familyName").as(String.class), likeExpression); break; case Patient.SP_NAME: gn1 = theBuilder.like(from.get("givenName1").as(String.class), likeExpression); gn2 = theBuilder.like(from.get("givenName2").as(String.class), likeExpression); Predicate fn1 = theBuilder.like(from.get("familyName").as(String.class), likeExpression); Predicate n1 = theBuilder.like(from.get("prefixName").as(String.class), likeExpression); Predicate n2 = theBuilder.like(from.get("suffixName").as(String.class), likeExpression); singleCode = theBuilder.or(gn1, gn2, fn1, n1, n2); break; default: break; } return singleCode; } @Override public Predicate translatePredicateDate(Class<? extends IResourceEntity> entity, CriteriaBuilder theBuilder, From<? extends IResourceEntity, ? extends IResourceEntity> from, DateRangeParam theRange, String theParamName, IQueryParameterType theParam) { Date lowerBound = theRange.getLowerBoundAsInstant(); Date upperBound = theRange.getUpperBoundAsInstant(); Calendar c = Calendar.getInstance(); Predicate ub = null; Predicate lb = null; switch (theParamName) { case Patient.SP_DEATHDATE: return super.translatePredicateDate(entity, theBuilder, from, theRange, theParamName, theParam); case Patient.SP_BIRTHDATE: if (lowerBound != null) { c.setTime(lowerBound); Predicate gt1 = theBuilder.greaterThan(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)); Predicate gt2 = theBuilder.and(theBuilder.equal(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)), theBuilder.greaterThan(from.get("monthOfBirth").as(Integer.class), c.get(Calendar.MONTH))); Predicate predicateDay = null; predicateDay = theBuilder.greaterThanOrEqualTo(from.get("dayOfBirth").as(Integer.class), c.get(Calendar.DAY_OF_MONTH)); Predicate gt3 = theBuilder.and(theBuilder.equal(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)), theBuilder.equal(from.get("monthOfBirth").as(Integer.class), c.get(Calendar.MONTH)), predicateDay); lb = theBuilder.or(gt1, gt2, gt3); } if (upperBound != null) { c.setTime(upperBound); Predicate lt1 = theBuilder.lessThan(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)); Predicate lt2 = theBuilder.and(theBuilder.equal(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)), theBuilder.lessThan(from.get("monthOfBirth").as(Integer.class), c.get(Calendar.MONTH))); Predicate predicateDay = null; predicateDay = theBuilder.lessThanOrEqualTo(from.get("dayOfBirth").as(Integer.class), c.get(Calendar.DAY_OF_MONTH)); Predicate lt3 = theBuilder.and(theBuilder.equal(from.get("yearOfBirth").as(Integer.class), c.get(Calendar.YEAR)), theBuilder.equal(from.get("monthOfBirth").as(Integer.class), c.get(Calendar.MONTH)), predicateDay); ub = theBuilder.or(lt1, lt2, lt3); } break; default: break; } if (lb != null && ub != null) { return (theBuilder.and(lb, ub)); } else if (lb != null) { return (lb); } else { return (ub); } } }; } }