001package org.hl7.fhir.r5.comparison; 002 003import java.io.IOException; 004import java.util.HashMap; 005import java.util.Map; 006import java.util.UUID; 007 008import org.hl7.fhir.exceptions.DefinitionException; 009import org.hl7.fhir.exceptions.FHIRException; 010import org.hl7.fhir.exceptions.FHIRFormatError; 011import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison; 012import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison; 013import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison; 014import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison; 015import org.hl7.fhir.r5.conformance.ProfileUtilities; 016import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider; 017import org.hl7.fhir.r5.context.IWorkerContext; 018import org.hl7.fhir.r5.model.CanonicalResource; 019import org.hl7.fhir.r5.model.CodeSystem; 020import org.hl7.fhir.r5.model.Resource; 021import org.hl7.fhir.r5.model.StructureDefinition; 022import org.hl7.fhir.r5.model.ValueSet; 023import org.hl7.fhir.utilities.Utilities; 024 025public class ComparisonSession { 026 027 private Map<String, ResourceComparison> compares = new HashMap<>(); 028 private IWorkerContext contextLeft; 029 private IWorkerContext contextRight; 030 private String sessiondId; 031 private int count; 032 private boolean debug; 033 private String title; 034 private ProfileKnowledgeProvider pkp; 035 036 public ComparisonSession(IWorkerContext contextLeft, IWorkerContext contextRight, String title, ProfileKnowledgeProvider pkp) { 037 super(); 038 this.contextLeft = contextLeft; 039 this.contextRight = contextRight; 040 this.sessiondId = UUID.randomUUID().toString().toLowerCase(); 041 this.title = title; 042 this.pkp = pkp; 043// debug = true; 044 } 045 046 public IWorkerContext getContextLeft() { 047 return contextLeft; 048 } 049 050 public IWorkerContext getContextRight() { 051 return contextRight; 052 } 053 054 public String getTitle() { 055 return title; 056 } 057 058 public ResourceComparison compare(String left, String right) throws DefinitionException, FHIRFormatError, IOException { 059 CanonicalResource l = (CanonicalResource) contextLeft.fetchResource(Resource.class, left); 060 if (l == null) { 061 throw new DefinitionException("Unable to resolve "+left); 062 } 063 CanonicalResource r = (CanonicalResource) contextRight.fetchResource(Resource.class, right); 064 if (r == null) { 065 throw new DefinitionException("Unable to resolve "+right); 066 } 067 return compare(l, r); 068 } 069 070 public ResourceComparison compare(CanonicalResource left, CanonicalResource right) throws DefinitionException, FHIRFormatError, IOException { 071 if (left != null && right != null) { 072 String key = key(left.getUrl(), left.getVersion(), right.getUrl(), right.getVersion()); 073 if (compares.containsKey(key)) { 074 // if null then the comparison is in progress. 075 // this can happen when profiles refer to each other 076 return compares.get(key); 077 } 078 compares.put(key, null); 079 try { 080 if (left instanceof CodeSystem && right instanceof CodeSystem) { 081 CodeSystemComparer cs = new CodeSystemComparer(this); 082 CodeSystemComparison csc = cs.compare((CodeSystem) left, (CodeSystem) right); 083 compares.put(key, csc); 084 return csc; 085 } else if (left instanceof ValueSet && right instanceof ValueSet) { 086 ValueSetComparer cs = new ValueSetComparer(this); 087 ValueSetComparison csc = cs.compare((ValueSet) left, (ValueSet) right); 088 compares.put(key, csc); 089 return csc; 090 } else if (left instanceof StructureDefinition && right instanceof StructureDefinition) { 091 ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(contextLeft, null, pkp), new ProfileUtilities(contextRight, null, pkp)); 092 ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right); 093 compares.put(key, csc); 094 return csc; 095 } else { 096 throw new FHIRException("Unable to compare resources of type "+left.fhirType()+" and "+right.fhirType()); 097 } 098 } catch (Throwable e) { 099 ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right, e); 100 compares.put(key, csc); 101 return csc; 102 } 103 } else if (left != null) { 104 String key = key(left.getUrl(), left.getVersion(), left.getUrl(), left.getVersion()); 105 if (compares.containsKey(key)) { 106 return compares.get(key); 107 } 108 ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right); 109 compares.put(key, csc); 110 return csc; 111 } else { 112 String key = key(right.getUrl(), right.getVersion(), right.getUrl(), right.getVersion()); 113 if (compares.containsKey(key)) { 114 return compares.get(key); 115 } 116 ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right); 117 compares.put(key, csc); 118 return csc; 119 } 120 } 121 122 private String key(String urlL, String verL, String urlR, String verR) { 123 return urlL+"|"+verL+"||"+urlR+"|"+verR; 124 } 125 126 public void identify(CanonicalResource res) { 127 count++; 128 res.setId(sessiondId+"-"+count); 129 res.setUrl("http://hl7.org/fhir/comparison/"+res.fhirType()+"/"+res.getId()); 130 } 131 132 public void identify(ResourceComparison res) { 133 count++; 134 } 135 136 public boolean isDebug() { 137 return debug; 138 } 139 140 public void setDebug(boolean debug) { 141 this.debug = debug; 142 } 143 144 public Map<String, ResourceComparison> getCompares() { 145 return compares; 146 } 147 148 public ProfileKnowledgeProvider getPkp() { 149 return pkp; 150 } 151}