package se.cambio.cds.util; import org.apache.log4j.Logger; import org.openehr.rm.datatypes.basic.DataValue; import org.openehr.rm.datatypes.text.DvCodedText; import se.cambio.cds.controller.guide.GuideManager; import se.cambio.cds.gdl.model.Guide; import se.cambio.cds.model.facade.execution.vo.*; import se.cambio.cds.model.instance.ArchetypeReference; import se.cambio.cds.model.instance.ElementInstance; import java.util.*; public class ElementInstanceCollection { public final static String EMPTY_CODE = "*EMPTY*"; private Map<String, Map<String, Map<String, Set<ArchetypeReference>>>> _archetypeReferenceMap = null; public void add(ElementInstance elementInstance){ add(elementInstance.getArchetypeReference(), null, null); } public void addAll(Collection<ElementInstance> elementInstances){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); for (ElementInstance elementInstance : elementInstances) { archetypeReferences.add(elementInstance.getArchetypeReference()); } addAll(archetypeReferences, null); } public void addAll(Collection<ArchetypeReference> archetypeReferences, GuideManager guideManager){ for (ArchetypeReference archetypeReferenceToAdd : archetypeReferences) { add(archetypeReferenceToAdd, guideManager, null); } } public void add(ArchetypeReference archetypeReferenceToAdd){ add(archetypeReferenceToAdd, null, null); } public void add(ArchetypeReference archetypeReferenceToAdd, GuideManager guideManager, Calendar date){ if (archetypeReferenceToAdd instanceof GeneratedArchetypeReference){ //Clone the AR ArchetypeReference arAux = archetypeReferenceToAdd.clone(); for (String idElement : archetypeReferenceToAdd.getElementInstancesMap().keySet()) { ElementInstance originalEI = archetypeReferenceToAdd.getElementInstancesMap().get(idElement); if (originalEI instanceof PredicateGeneratedElementInstance){ PredicateGeneratedElementInstance predicateOriginalEI = (PredicateGeneratedElementInstance)originalEI; //Its a predicate, so keep it as a generated element instance, but resolve the data value DataValue dv = originalEI.getDataValue(); if (guideManager!=null){ Set<Guide> guides = getGuides(guideManager, predicateOriginalEI, dv); dv = ElementInstanceCollectionUtil.resolvePredicate(dv, predicateOriginalEI.getOperatorKind(), guides, date); //Might be null i.e. max(date/time) or path!=null } PredicateGeneratedElementInstance pgei = new PredicateGeneratedElementInstanceBuilder() .setId(predicateOriginalEI.getId()) .setDataValue(dv) .setArchetypeReference(arAux) .setOperatorKind(predicateOriginalEI.getOperatorKind()) .createPredicateGeneratedElementInstance(); pgei.setRuleReferences(predicateOriginalEI.getRuleReferences()); //Should not allow value changes for generated elements in the future }else{ //Clone a new instance /* GeneratedElementInstance gei = new GeneratedElementInstance( originalEI.getId(), null, arAux, null, null); */ ElementInstance ei = originalEI.clone(); ei.setArchetypeReference(arAux); if (originalEI instanceof GeneratedElementInstance){ GeneratedElementInstance generatedElementInstance = (GeneratedElementInstance)originalEI; ((GeneratedElementInstance)ei).setRuleReferences(generatedElementInstance.getRuleReferences()); } } } archetypeReferenceToAdd = arAux; } Set<ArchetypeReference> archetypeReferencesInCollection = getArchetypeReferences(archetypeReferenceToAdd); //Remove empty (first) AR if existent //DISCARDED: There might be a need for an empty instance (CHA2DS2VASc) //ArchetypeReference arAux2 = ElementInstanceCollectionUtil.getEmptyArchetypeReference(archetypeReferencesInCollection); //if (arAux2!=null){ // remove(arAux2); //} //System.out.println("Addding:\n"+archetypeReferenceToAdd.toString()); archetypeReferencesInCollection.add(archetypeReferenceToAdd); } private Set<Guide> getGuides(GuideManager guideManager, GeneratedElementInstance predicateOriginalEI, DataValue dv) { Set<Guide> guides = new HashSet<Guide>(); Collection<String> guideIds = getReferenceGuideIds(dv, predicateOriginalEI.getRuleReferences()); for(String guideId: guideIds){ Guide guide = guideManager.getGuide(guideId); if (guide==null){ Logger.getLogger(ElementInstanceCollectionUtil.class).warn("Guideline not found resolving rule reference '"+guide+"'"); }else{ guides.add(guide); } } return guides; } public Collection<String> getReferenceGuideIds(DataValue dv, Collection<RuleReference> ruleReferences){ Collection<String> guideIds = new ArrayList<String>(); if (dv instanceof DvCodedText){ DvCodedText dvCT = (DvCodedText)dv; for(RuleReference ruleReference: ruleReferences){ if (ruleReference.getGTCode().equals(dvCT.getCode())){ guideIds.add(ruleReference.getGuideId()); } } } else { for(RuleReference ruleReference: ruleReferences){ guideIds.add(ruleReference.getGuideId()); } } return guideIds; } public void remove(ArchetypeReference archetypeReference){ getArchetypeReferences(archetypeReference).remove(archetypeReference); } public void removeDomain(String idDomain){ for (String idArchetype : getArchetypeReferenceMap().keySet()) { getArchetypeReferenceMap(idArchetype, idDomain).clear(); } } /* public boolean matches(GeneratedElementInstance elementInstance, GuideManager guideManager){ return matches((GeneratedArchetypeReference)elementInstance.getArchetypeReference(), guideManager); } */ public boolean matches(GeneratedArchetypeReference generatedArchetypeReference, Map<String, Guide> guideMap, Calendar date){ boolean matches = false; Iterator<ArchetypeReference> i = getArchetypeReferences(generatedArchetypeReference).iterator(); while(i.hasNext() && !matches){ ArchetypeReference ar = i.next(); matches = ElementInstanceCollectionUtil.matchAndFill(generatedArchetypeReference, ar, guideMap, date); } return matches; } /* public boolean contains(ArchetypeReference archetypeReference){ for (ElementInstance elementInstance : elementInstances) { boolean containsElement = getElementInstances(elementInstance).isEmpty(); if (!containsElement){ return false; } } return true; } public Set<ElementInstance> getAllElementInstances(String idArchetype, String idDomain, String idAux){ Set<ElementInstance> elementInstances = new HashSet<ElementInstance>(); if (idDomain!=null && idAux!=null){ for (Collection<ElementInstance> elementInstancesAux : getArchetypeReferences(idArchetype, idDomain, idAux).values()) { elementInstances.addAll(elementInstancesAux); }; }else{ for (Collection<ElementInstance> elementInstancesAux : getArchetypeReferencesCheckIdDomainAndIdAux(idArchetype, idDomain, idAux).values()) { elementInstances.addAll(elementInstancesAux); } } return elementInstances; }*/ public Set<String> getElementIdsByIdDomain(String idDomain){ Set<String> idElements = new HashSet<String>(); Set<ElementInstance> elementInstances = getAllElementInstancesByDomain(idDomain); for (ElementInstance elementInstance : elementInstances) { idElements.add(elementInstance.getId()); } return idElements; } public Collection<ElementInstance> getAllElementInstances(){ Collection<ElementInstance> elementInstances = new ArrayList<ElementInstance>(); for (ArchetypeReference ar : getAllArchetypeReferences()) { elementInstances.addAll(ar.getElementInstancesMap().values()); } return elementInstances; } public Set<ArchetypeReference> getAllArchetypeReferences(){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); for (String idArchetype : getArchetypeReferenceMap().keySet()) { archetypeReferences.addAll(getAllArchetypeReferences(idArchetype)); } return archetypeReferences; } public Set<ElementInstance> getAllElementInstancesByDomain(String idDomain){ Set<ElementInstance> elementInstances = new HashSet<ElementInstance>(); for (ArchetypeReference archetypeReference : getAllArchetypeReferencesByDomain(idDomain)) { elementInstances.addAll(archetypeReference.getElementInstancesMap().values()); } return elementInstances; } /* public Set<ArchetypeReference> getArchetypeReferencesByDomain(String idDomain){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); for (String idArchetype : getArchetypeReferenceMap().keySet()) { archetypeReferences.addAll(getAllArchetypeReferences(idArchetype, idDomain)); } return archetypeReferences; } */ public void merge(Collection<ElementInstanceCollection> elementInstanceCollections){ for (ElementInstanceCollection eic : elementInstanceCollections) { this.merge(eic); } } public void merge(ElementInstanceCollection eic){ for (ArchetypeReference archetypeReference : eic.getAllArchetypeReferences()) { add(archetypeReference); } } public Set<ArchetypeReference> getArchetypeReferences(ArchetypeReference archetypeReference){ String idDomain = archetypeReference.getIdDomain()!=null?archetypeReference.getIdDomain():EMPTY_CODE; String idAux = null; if (Domains.CDS_ID.equals(idDomain)){ idAux = archetypeReference.getIdTemplate(); } if (idAux==null){ idAux = EMPTY_CODE; } return getArchetypeReferences(archetypeReference.getIdArchetype(), idDomain, idAux); } public Set<ArchetypeReference> getArchetypeReferencesEmptyAsWildcard(ArchetypeReference ar){ String idDomain = ar.getIdDomain(); String idAux = null; if (Domains.CDS_ID.equals(idDomain)){ idAux = ar.getIdTemplate(); } if (idDomain==null){ Set<ArchetypeReference> arSet = new HashSet<ArchetypeReference>(); arSet.addAll(getArchetypeReferencesEmptyAsWildcard(ar.getIdArchetype(), Domains.CDS_ID, idAux)); arSet.addAll(getArchetypeReferencesEmptyAsWildcard(ar.getIdArchetype(), Domains.EHR_ID, idAux)); return arSet; }else{ return getArchetypeReferencesEmptyAsWildcard(ar.getIdArchetype(), idDomain, idAux); } } private Set<ArchetypeReference> getArchetypeReferencesEmptyAsWildcard(String idArchetype, String idDomain, String idAux){ Set<ArchetypeReference> arSet = new HashSet<ArchetypeReference>(); if (idAux==null){ for (Set<ArchetypeReference> arSetAux : getArchetypeReferenceMap(idArchetype, idDomain).values()) { arSet.addAll(arSetAux); } }else{ arSet.addAll( getArchetypeReferences(idArchetype, idDomain, idAux)); } return arSet; } /* private Set<ArchetypeReference> getArchetypeReferencesCheckIdDomainAndIdAux(String idArchetype, String idDomain, String idAux){ if (idDomain==null){ if (idAux==null){ return getAllArchetypeReferences(idArchetype); }else{ return getAllArchetypeReferencesNoIdDomain(idArchetype, idAux); } }else{ return getArchetypeReferencesCheckIdAux(idArchetype, idDomain, idAux); } } private Set<ArchetypeReference> getArchetypeReferencesCheckIdAux(String idArchetype, String idDomain, String idAux){ if (idAux==null){ return getAllArchetypeReferences(idArchetype, idDomain); }else{ return getArchetypeReferences(idArchetype, idDomain, idAux); } } private Set<ArchetypeReference> getAllArchetypeReferencesNoIdDomain(String idArchetype, String idAux){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); Map<String, Map<String, Set<ArchetypeReference>>> archetypeReferencesMap = getArchetypeReferenceMap(idArchetype); for (String idDomain : archetypeReferencesMap.keySet()) { archetypeReferences.addAll(getArchetypeReferences(idArchetype, idDomain, idAux)); } return archetypeReferences; } */ private Set<ArchetypeReference> getAllArchetypeReferences(String idArchetype){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); for (String idDomain : getArchetypeReferenceMap(idArchetype).keySet()) { archetypeReferences.addAll(getAllArchetypeReferences(idArchetype, idDomain)); } return archetypeReferences; } private Set<ArchetypeReference> getAllArchetypeReferences(String idArchetype, String idDomain){ Set<ArchetypeReference> archetypeReferences = new HashSet<ArchetypeReference>(); Map<String, Set<ArchetypeReference>> archetypeReferencesMap = getArchetypeReferenceMap(idArchetype, idDomain); for (String idAux : archetypeReferencesMap.keySet()) { archetypeReferences.addAll(archetypeReferencesMap.get(idAux)); } return archetypeReferences; } /* private Set<ElementInstance> getElementInstances(String idArchetype, String idDomain, String idAux, String elementId){ if (elementId==null){ Logger.getLogger(ElementInstanceCollection.class).warn("Call to getElementInstances with elementId=='null'"); } Set<ArchetypeReference> archetypeReferences = getArchetypeReferences(idArchetype, idDomain, idAux); Set<ElementInstance> elementInstances = new HashSet<ElementInstance>(); for (ArchetypeReference archetypeReference : archetypeReferences) { elementInstances.add(archetypeReference.getElementInstancesMap().get(elementId)); } return elementInstances; } */ private Set<ArchetypeReference> getArchetypeReferences(String idArchetype, String idDomain, String idAux){ if (idAux==null){ Logger.getLogger(ElementInstanceCollection.class).warn("Call to getArchetypeReferences with idAux=='null'"); } Set<ArchetypeReference> archetypeReferences = getArchetypeReferenceMap(idArchetype, idDomain).get(idAux); if (archetypeReferences==null){ archetypeReferences = new HashSet<ArchetypeReference>(); getArchetypeReferenceMap(idArchetype, idDomain).put(idAux, archetypeReferences); } return archetypeReferences; } private Map<String, Set<ArchetypeReference>> getArchetypeReferenceMap(String idArchetype, String idDomain){ if (idDomain==null){ Logger.getLogger(ElementInstanceCollection.class).warn("Call to getArchetypeReferenceMap with idDomain=='null'"); } Map<String, Set<ArchetypeReference>> archetypeReferenceMap = getArchetypeReferenceMap(idArchetype).get(idDomain); if (archetypeReferenceMap==null){ archetypeReferenceMap = new HashMap<String, Set<ArchetypeReference>>(); getArchetypeReferenceMap(idArchetype).put(idDomain, archetypeReferenceMap); } return archetypeReferenceMap; } private Map<String, Map<String, Set<ArchetypeReference>>> getArchetypeReferenceMap(String idArchetype){ Map<String, Map<String, Set<ArchetypeReference>>> archetypeReferenceMap = getArchetypeReferenceMap().get(idArchetype); if (archetypeReferenceMap==null){ archetypeReferenceMap = new HashMap<String, Map<String, Set<ArchetypeReference>>>(); getArchetypeReferenceMap().put(idArchetype, archetypeReferenceMap); } return archetypeReferenceMap; } public Collection<ArchetypeReference> getAllArchetypeReferencesByDomain(String domainId){ Collection<ArchetypeReference> ars = new ArrayList<ArchetypeReference>(); for (String idArchetype : getArchetypeReferenceMap().keySet()) { ars.addAll(getAllArchetypeReferences(idArchetype, domainId)); } return ars; } private Map< String, Map<String,Map<String, Set<ArchetypeReference>>>> getArchetypeReferenceMap(){ if (_archetypeReferenceMap==null){ _archetypeReferenceMap = new HashMap<String, Map<String,Map<String, Set<ArchetypeReference>>>>(); } return _archetypeReferenceMap; } public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("-----\n"); for (String idArchetype : getArchetypeReferenceMap().keySet()) { sb.append(idArchetype+"\n"); for (String idDomain : getArchetypeReferenceMap(idArchetype).keySet()) { sb.append("-Domain="+idDomain+"\n"); for (String idAux : getArchetypeReferenceMap(idArchetype, idDomain).keySet()) { sb.append("--idAux="+idAux+"\n"); int i = 1; for (ArchetypeReference ar : getArchetypeReferences(idArchetype, idDomain, idAux)) { sb.append("---["+i+"]\n"); for (String idElement : ar.getElementInstancesMap().keySet()) { sb.append("----"+idElement+""); ElementInstance ei = ar.getElementInstancesMap().get(idElement); if (ei.getDataValue()!=null){ sb.append(" ("+ei.getDataValue().toString()+")"); } sb.append("\n"); } } } } } sb.append("-----\n"); return sb.toString(); } } /* * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 2.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * * The Initial Developers of the Original Code are Iago Corbal and Rong Chen. * Portions created by the Initial Developer are Copyright (C) 2012-2013 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * ***** END LICENSE BLOCK ***** */