package se.cambio.cds.util; import org.apache.log4j.Logger; import org.openehr.rm.datatypes.basic.DataValue; import se.cambio.cds.gdl.model.expression.OperatorKind; import se.cambio.cds.model.facade.execution.vo.PredicateGeneratedElementInstance; import se.cambio.cds.model.instance.ArchetypeReference; import se.cambio.cds.model.instance.ElementInstance; import java.util.Calendar; import java.util.Collection; import java.util.HashSet; import java.util.Set; /** * User: iago.corbal * Date: 2013-12-10 * Time: 09:23 */ public class PredicateFilterUtil { public static void filterByPredicates( Collection<ArchetypeReference> definitionArchetypeReferences, Collection<ArchetypeReference> ehrArchetypeReferences, Calendar date){ for (ArchetypeReference archetypeReference: definitionArchetypeReferences){ for (ElementInstance elementInstance: archetypeReference.getElementInstancesMap().values()){ if(hasOtherPredicates(elementInstance, definitionArchetypeReferences)){ continue; } if (elementInstance instanceof PredicateGeneratedElementInstance) { PredicateGeneratedElementInstance pgei = (PredicateGeneratedElementInstance) elementInstance; if (OperatorKind.MAX.equals(pgei.getOperatorKind())){ filterMaxMin(pgei.getId(), ehrArchetypeReferences, true); }else if (OperatorKind.MIN.equals(pgei.getOperatorKind())){ filterMaxMin(pgei.getId(), ehrArchetypeReferences, false); }else if (OperatorKind.GREATER_THAN_OR_EQUAL.equals(pgei.getOperatorKind())){ filterGreaterLessThanPredicate(pgei.getId(), pgei.getDataValue(), ehrArchetypeReferences, true, date); }else if (OperatorKind.LESS_THAN_OR_EQUAL.equals(pgei.getOperatorKind())){ filterGreaterLessThanPredicate(pgei.getId(), pgei.getDataValue(), ehrArchetypeReferences, false, date); } } } } } private static void filterMaxMin(String elementId, Collection<ArchetypeReference> ehrArchetypeReferences, boolean max){ final Set<ArchetypeReference> archetypeReferencesToRemove = new HashSet<ArchetypeReference>(); ElementInstance maxElementInstance = null; for (ArchetypeReference archetypeReference: ehrArchetypeReferences){ ElementInstance elementInstance = archetypeReference.getElementInstancesMap().get(elementId); if (elementInstance!=null){ if (elementInstance.getDataValue()!=null){ if (maxElementInstance==null || isMaxMin(elementInstance, maxElementInstance, max)){ if (maxElementInstance!=null){ archetypeReferencesToRemove.add(maxElementInstance.getArchetypeReference()); } maxElementInstance = elementInstance; }else{ archetypeReferencesToRemove.add(elementInstance.getArchetypeReference()); } }else{ archetypeReferencesToRemove.add(elementInstance.getArchetypeReference()); } } } ehrArchetypeReferences.removeAll(archetypeReferencesToRemove); } private static void filterGreaterLessThanPredicate( String elementId, DataValue dv, Collection<ArchetypeReference> ehrArchetypeReferences, boolean greaterThan, Calendar date){ if (dv instanceof CurrentTimeExpressionDataValue){ dv = ElementInstanceCollectionUtil.resolvePredicate(dv, OperatorKind.GREATER_THAN_OR_EQUAL, null, date); if (dv==null){ Logger.getLogger(PredicateFilterUtil.class).warn("No Data Value returned after resolving predicate!"); } } final Set<ArchetypeReference> archetypeReferencesToRemove = new HashSet<ArchetypeReference>(); for (ArchetypeReference archetypeReference: ehrArchetypeReferences){ ElementInstance elementInstance = archetypeReference.getElementInstancesMap().get(elementId); if (elementInstance!=null){ if (elementInstance.getDataValue()!=null){ int compare = DVUtil.compareDVs(dv, elementInstance.getDataValue()); if (compare!=0 && ((greaterThan && compare>0)||(!greaterThan && compare<0))){ archetypeReferencesToRemove.add(elementInstance.getArchetypeReference()); } }else{ archetypeReferencesToRemove.add(elementInstance.getArchetypeReference()); } } } ehrArchetypeReferences.removeAll(archetypeReferencesToRemove); } private static boolean isMaxMin(ElementInstance elementInstance, ElementInstance maxElementInstance, boolean max){ int compare = DVUtil.compareDVs(elementInstance.getDataValue(), maxElementInstance.getDataValue()); if (max){ return compare>0; }else{ return compare<0; } } //Check if there are other predicates in archetype references with same archetype Id. If so -> skip private static boolean hasOtherPredicates(ElementInstance elementInstance, Collection<ArchetypeReference> archetypeReferences){ ArchetypeReference ar = elementInstance.getArchetypeReference(); for(ArchetypeReference archetypeReference: archetypeReferences){ if (ar.getIdArchetype().equals(archetypeReference.getIdArchetype())){ for (ElementInstance elementInstanceAux: archetypeReference.getElementInstancesMap().values()){ if (elementInstanceAux instanceof PredicateGeneratedElementInstance && !elementInstanceAux.equals(elementInstance)){ return true; } } } } return false; } }