Merge pull request #844 from hapifhir/gg-202206-amsterdam
Gg 202206 amsterdam
This commit is contained in:
commit
95dee12d0e
|
@ -133,7 +133,7 @@ class FHIRToolingClientTest {
|
|||
|
||||
private void checkHeaders(Headers argumentCaptorValue) {
|
||||
getHeaders().forEach(header -> {
|
||||
System.out.println("Checking header <" + header.component1().utf8() + ", " + header.component2().utf8() + ">");
|
||||
// System.out.println("Checking header <" + header.component1().utf8() + ", " + header.component2().utf8() + ">");
|
||||
Assertions.assertEquals(argumentCaptorValue.get(header.component1().utf8()), header.component2().utf8());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Map;
|
|||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.BackboneElement;
|
||||
|
@ -86,7 +88,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
super(session);
|
||||
}
|
||||
|
||||
public CapabilityStatementComparison compare(CapabilityStatement left, CapabilityStatement right) {
|
||||
public CapabilityStatementComparison compare(CapabilityStatement left, CapabilityStatement right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
if (left == null)
|
||||
throw new DefinitionException("No CapabilityStatement provided (left)");
|
||||
if (right == null)
|
||||
|
@ -130,7 +132,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
return res;
|
||||
}
|
||||
|
||||
private void compareRests(List<CapabilityStatementRestComponent> left, List<CapabilityStatementRestComponent> right, StructuralMatch<Element> combined, List<CapabilityStatementRestComponent> union, List<CapabilityStatementRestComponent> intersection, CapabilityStatement csU, CapabilityStatement csI, CapabilityStatementComparison res, String path) {
|
||||
private void compareRests(List<CapabilityStatementRestComponent> left, List<CapabilityStatementRestComponent> right, StructuralMatch<Element> combined, List<CapabilityStatementRestComponent> union, List<CapabilityStatementRestComponent> intersection, CapabilityStatement csU, CapabilityStatement csI, CapabilityStatementComparison res, String path) throws DefinitionException, FHIRFormatError, IOException {
|
||||
List<CapabilityStatementRestComponent> matchR = new ArrayList<>();
|
||||
for (CapabilityStatementRestComponent l : left) {
|
||||
CapabilityStatementRestComponent r = findInList(right, l);
|
||||
|
@ -203,10 +205,12 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
combined.getChildren().add(sm);
|
||||
}
|
||||
}
|
||||
for (CodeableConcept r : right.getService()) {
|
||||
if (!matchR.contains(r)) {
|
||||
union.getService().add(r);
|
||||
combined.getChildren().add(new StructuralMatch<Element>(vmI(IssueSeverity.INFORMATION, "Added this concept", path), r));
|
||||
if (right != null) {
|
||||
for (CodeableConcept r : right.getService()) {
|
||||
if (!matchR.contains(r)) {
|
||||
union.getService().add(r);
|
||||
combined.getChildren().add(new StructuralMatch<Element>(vmI(IssueSeverity.INFORMATION, "Added this concept", path), r));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -384,7 +388,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
tgt.removeAll(toRemove);
|
||||
}
|
||||
|
||||
private void compareRestResources(CapabilityStatementRestComponent left, CapabilityStatementRestComponent right, StructuralMatch<Element> combined, CapabilityStatementRestComponent union, CapabilityStatementRestComponent intersection, CapabilityStatement csU, CapabilityStatement csI, CapabilityStatementComparison res, String path) {
|
||||
private void compareRestResources(CapabilityStatementRestComponent left, CapabilityStatementRestComponent right, StructuralMatch<Element> combined, CapabilityStatementRestComponent union, CapabilityStatementRestComponent intersection, CapabilityStatement csU, CapabilityStatement csI, CapabilityStatementComparison res, String path) throws DefinitionException, FHIRFormatError, IOException {
|
||||
List<CapabilityStatementRestResourceComponent> matchR = new ArrayList<>();
|
||||
for (CapabilityStatementRestResourceComponent l : left.getResource()) {
|
||||
CapabilityStatementRestResourceComponent r = findInList(right.getResource(), l);
|
||||
|
@ -410,7 +414,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
}
|
||||
|
||||
private void compareRestResource(StructuralMatch<Element> sm, CapabilityStatementRestResourceComponent l, CapabilityStatementRestResourceComponent r, String path, CapabilityStatementComparison res, CapabilityStatementRestResourceComponent union, CapabilityStatementRestResourceComponent intersection) {
|
||||
private void compareRestResource(StructuralMatch<Element> sm, CapabilityStatementRestResourceComponent l, CapabilityStatementRestResourceComponent r, String path, CapabilityStatementComparison res, CapabilityStatementRestResourceComponent union, CapabilityStatementRestResourceComponent intersection) throws DefinitionException, FHIRFormatError, IOException {
|
||||
compareProfiles(path, sm, l.getProfileElement(), r.getProfileElement(), res, union, intersection);
|
||||
// todo: supported profiles
|
||||
compareStrings(path, sm.getMessages(), l.getDocumentation(), r.getDocumentation(), "documentation", IssueSeverity.INFORMATION, res);
|
||||
|
@ -430,7 +434,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
compareOperations(sm, l.getOperation(), r.getOperation(), path, res, union.getOperation(), intersection.getOperation());
|
||||
}
|
||||
|
||||
private void compareProfiles(String path, StructuralMatch<Element> combined, CanonicalType left, CanonicalType right, CapabilityStatementComparison res, CapabilityStatementRestResourceComponent union, CapabilityStatementRestResourceComponent intersection) {
|
||||
private void compareProfiles(String path, StructuralMatch<Element> combined, CanonicalType left, CanonicalType right, CapabilityStatementComparison res, CapabilityStatementRestResourceComponent union, CapabilityStatementRestResourceComponent intersection) throws DefinitionException, FHIRFormatError, IOException {
|
||||
if (!left.hasValue() && !right.hasValue()) {
|
||||
// nothing in this case
|
||||
} else if (!left.hasValue()) {
|
||||
|
@ -466,7 +470,9 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
combined.getChildren().add(new StructuralMatch<Element>(left, right, vmI(IssueSeverity.WARNING, "Changed this profile to a narrower one", path)).setName("profile"));
|
||||
} else {
|
||||
combined.getChildren().add(new StructuralMatch<Element>(left, right, vmI(IssueSeverity.WARNING, "Different", path)).setName("profile"));
|
||||
throw new Error("Not done yet");
|
||||
ProfileComparison pc = (ProfileComparison) session.compare(sdLeft, sdRight);
|
||||
intersection.setProfile(pc.getIntersection().getUrl());
|
||||
union.setProfile(pc.getUnion().getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Set;
|
|||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.PlaceHolderComparison;
|
||||
|
@ -133,6 +134,8 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
renderValueSet(id, (ValueSetComparison) comp);
|
||||
} else if (comp instanceof CodeSystemComparison) {
|
||||
renderCodeSystem(id, (CodeSystemComparison) comp);
|
||||
} else if (comp instanceof CapabilityStatementComparison) {
|
||||
renderCapabilityStatement(id, (CapabilityStatementComparison) comp);
|
||||
} else if (comp instanceof PlaceHolderComparison) {
|
||||
renderPlaceHolder(id, (PlaceHolderComparison) comp);
|
||||
}
|
||||
|
@ -211,6 +214,25 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(folder, comp.getId() + "-union.json")), comp.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(folder, comp.getId() + "-intersection.json")), comp.getIntersection());
|
||||
}
|
||||
|
||||
private void renderCapabilityStatement(String id, CapabilityStatementComparison comp) throws IOException {
|
||||
String template = templates.get("CapabilityStatement");
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
CapabilityStatementComparer cs = new CapabilityStatementComparer(session);
|
||||
vars.put("left", new StringType(comp.getLeft().present()));
|
||||
vars.put("right", new StringType(comp.getRight().present()));
|
||||
vars.put("leftId", new StringType(comp.getLeft().getId()));
|
||||
vars.put("rightId", new StringType(comp.getRight().getId()));
|
||||
vars.put("leftUrl", new StringType(comp.getLeft().getUrl()));
|
||||
vars.put("rightUrl", new StringType(comp.getRight().getUrl()));
|
||||
vars.put("errors", new StringType(new XhtmlComposer(true).compose(cs.renderErrors(comp))));
|
||||
vars.put("metadata", new StringType(new XhtmlComposer(true).compose(cs.renderMetadata(comp, "", ""))));
|
||||
vars.put("statement", new StringType(new XhtmlComposer(true).compose(cs.renderStatements(comp, "", ""))));
|
||||
String cnt = processTemplate(template, "CapabilityStatement", vars);
|
||||
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(folder, comp.getId() + "-union.json")), comp.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(folder, comp.getId() + "-intersection.json")), comp.getIntersection());
|
||||
}
|
||||
|
||||
private String processTemplate(String template, String name, Map<String, Base> vars) {
|
||||
LiquidEngine engine = new LiquidEngine(contextRight, this);
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.UUID;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||
|
@ -16,6 +17,7 @@ import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
|||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -24,6 +26,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
|
||||
public class ComparisonSession {
|
||||
|
||||
|
||||
private Map<String, ResourceComparison> compares = new HashMap<>();
|
||||
private IWorkerContext contextLeft;
|
||||
private IWorkerContext contextRight;
|
||||
|
@ -42,7 +45,7 @@ public class ComparisonSession {
|
|||
this.title = title;
|
||||
this.pkpLeft = pkpLeft;
|
||||
this.pkpRight = pkpRight;
|
||||
// debug = true;
|
||||
debug = false;
|
||||
}
|
||||
|
||||
public IWorkerContext getContextLeft() {
|
||||
|
@ -94,10 +97,18 @@ public class ComparisonSession {
|
|||
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof CapabilityStatement && right instanceof CapabilityStatement) {
|
||||
CapabilityStatementComparer cs = new CapabilityStatementComparer(this);
|
||||
CapabilityStatementComparison csc = cs.compare((CapabilityStatement) left, (CapabilityStatement) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else {
|
||||
throw new FHIRException("Unable to compare resources of type "+left.fhirType()+" and "+right.fhirType());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right, e);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
|
|
|
@ -19,10 +19,12 @@ import org.hl7.fhir.r5.model.Base;
|
|||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.AggregationMode;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionMappingComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
|
@ -539,10 +541,13 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
boolean pfound = false;
|
||||
boolean tfound = false;
|
||||
nw = nw.copy();
|
||||
if (nw.hasAggregation())
|
||||
throw new DefinitionException("Aggregation not supported: "+path);
|
||||
for (TypeRefComponent ex : results) {
|
||||
if (Utilities.equals(ex.getWorkingCode(), nw.getWorkingCode())) {
|
||||
for (Enumeration<AggregationMode> a : nw.getAggregation()) {
|
||||
if (!ex.hasAggregation(a.getValue())) {
|
||||
ex.addAggregation(a.getValue());
|
||||
}
|
||||
}
|
||||
if (!ex.hasProfile() && !nw.hasProfile())
|
||||
pfound = true;
|
||||
else if (!ex.hasProfile()) {
|
||||
|
@ -635,14 +640,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
private Collection<? extends TypeRefComponent> intersectTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition ed, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||
for (TypeRefComponent l : left) {
|
||||
if (l.hasAggregation())
|
||||
throw new DefinitionException("Aggregation not supported: "+path);
|
||||
boolean pfound = false;
|
||||
boolean tfound = false;
|
||||
TypeRefComponent c = l.copy();
|
||||
for (TypeRefComponent r : right) {
|
||||
if (r.hasAggregation())
|
||||
throw new DefinitionException("Aggregation not supported: "+path);
|
||||
if (!l.hasProfile() && !r.hasProfile()) {
|
||||
pfound = true;
|
||||
} else if (!r.hasProfile()) {
|
||||
|
@ -697,9 +698,17 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (pfound && tfound) {
|
||||
for (Enumeration<AggregationMode> a : l.getAggregation()) {
|
||||
if (!r.hasAggregation(a.getValue())) {
|
||||
c.getAggregation().removeIf(n -> n.getValue() == a.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pfound && tfound)
|
||||
if (pfound && tfound) {
|
||||
result.add(c);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
|||
|
||||
if (matchCount == 1 && sourceCount == 1) {
|
||||
for (ConceptSetComponent t : matches) {
|
||||
if (t.getSystem().equals(item.getSystem())) {
|
||||
if (t.getSystem() != null && t.getSystem().equals(item.getSystem())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,13 +56,17 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.elementmodel.Property;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeType;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
|
@ -106,6 +110,7 @@ import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
|||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.UsageContext;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
||||
|
@ -125,6 +130,10 @@ import org.hl7.fhir.utilities.MarkDownProcessor;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
@ -6838,4 +6847,99 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
this.masterSourceFileNames = masterSourceFileNames;
|
||||
}
|
||||
|
||||
}
|
||||
public static int loadR5Extensions(BasePackageCacheManager pcm, IWorkerContext context) throws FHIRException, IOException {
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
String[] types = new String[] { "StructureDefinition", "ValueSet", "CodeSystem" };
|
||||
Map<String, ValueSet> valueSets = new HashMap<>();
|
||||
Map<String, CodeSystem> codeSystems = new HashMap<>();
|
||||
List<StructureDefinition> extensions = new ArrayList<>();
|
||||
JsonParser json = new JsonParser();
|
||||
for (PackageResourceInformation pri : npm.listIndexedResources(types)) {
|
||||
CanonicalResource r = (CanonicalResource) json.parse(npm.load(pri));
|
||||
if (r instanceof CodeSystem) {
|
||||
codeSystems.put(r.getUrl(), (CodeSystem) r);
|
||||
} else if (r instanceof ValueSet) {
|
||||
valueSets.put(r.getUrl(), (ValueSet) r);
|
||||
} else if (r instanceof StructureDefinition) {
|
||||
extensions.add((StructureDefinition) r);
|
||||
}
|
||||
}
|
||||
PackageVersion pd = new PackageVersion(npm.name(), npm.version(), npm.dateAsDate());
|
||||
int c = 0;
|
||||
List<String> typeNames = context.getTypeNames();
|
||||
for (StructureDefinition sd : extensions) {
|
||||
if (sd.getType().equals("Extension") && sd.getDerivation() == TypeDerivationRule.CONSTRAINT &&
|
||||
!context.hasResource(StructureDefinition.class, sd.getUrl())) {
|
||||
if (survivesStrippingTypes(sd, context, typeNames)) {
|
||||
c++;
|
||||
sd.setUserData("path", Utilities.pathURL(npm.getWebLocation(), "extension-"+sd.getId()+".html"));
|
||||
context.cacheResourceFromPackage(sd, pd);
|
||||
registerTerminologies(sd, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void registerTerminologies(StructureDefinition sd, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
|
||||
String vs = ed.getBinding().getValueSet();
|
||||
if (!context.hasResource(StructureDefinition.class, vs)) {
|
||||
loadValueSet(vs, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void loadValueSet(String url, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
if (valueSets.containsKey(url)) {
|
||||
ValueSet vs = valueSets.get(url);
|
||||
context.cacheResourceFromPackage(vs, pd);
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
for (CanonicalType t : inc.getValueSet()) {
|
||||
loadValueSet(t.asStringValue(), context, valueSets, codeSystems, pd);
|
||||
}
|
||||
if (inc.hasSystem()) {
|
||||
if (!context.hasResource(CodeSystem.class, inc.getSystem()) && codeSystems.containsKey(inc.getSystem())) {
|
||||
context.cacheResourceFromPackage(codeSystems.get(inc.getSystem()), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean survivesStrippingTypes(StructureDefinition sd, IWorkerContext context, List<String> typeNames) {
|
||||
for (ElementDefinition ed : sd.getDifferential().getElement()) {
|
||||
stripTypes(ed, context, typeNames);
|
||||
}
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (!stripTypes(ed, context, typeNames)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean stripTypes(ElementDefinition ed, IWorkerContext context, List<String> typeNames) {
|
||||
if (!ed.getPath().contains(".") || !ed.hasType()) {
|
||||
return true;
|
||||
}
|
||||
ed.getType().removeIf(tr -> !typeNames.contains(tr.getWorkingCode()));
|
||||
if (!ed.hasType()) {
|
||||
return false;
|
||||
}
|
||||
for (TypeRefComponent tr : ed.getType()) {
|
||||
if (tr.hasTargetProfile()) {
|
||||
tr.getTargetProfile().removeIf(n -> !context.hasResource(StructureDefinition.class, n.asStringValue()));
|
||||
if (!tr.hasTargetProfile()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -487,7 +487,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
t++;
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, s, pi.name(), pi.version(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (types.length == 0) {
|
||||
|
|
|
@ -98,7 +98,7 @@ import org.slf4j.LoggerFactory;
|
|||
public abstract class JsonParserBase extends ParserBase implements IParser {
|
||||
|
||||
static {
|
||||
LoggerFactory.getLogger("org.hl7.fhir.r5.formats.XmlParserBase").debug("XML Parser is being loaded");
|
||||
LoggerFactory.getLogger("org.hl7.fhir.r5.formats.JsonParserBase").debug("JSON Parser is being loaded");
|
||||
ClassesLoadedFlags.ourJsonParserBaseLoaded = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -916,7 +916,7 @@ public class DataRenderer extends Renderer {
|
|||
CodeSystem cs = context.getWorker().fetchCodeSystem(system, version);
|
||||
if (cs != null && cs.hasUserData("path")) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return cs.getUserString("path")+"#"+Utilities.nmtokenize(code);
|
||||
return cs.getUserString("path")+"#"+cs.getId()+"-"+Utilities.nmtokenize(code);
|
||||
} else {
|
||||
return cs.getUserString("path");
|
||||
}
|
||||
|
@ -932,8 +932,9 @@ public class DataRenderer extends Renderer {
|
|||
if (Utilities.noString(s))
|
||||
s = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||
|
||||
CodeSystem cs = context.getWorker().fetchCodeSystem(c.getSystem());
|
||||
|
||||
String sn = describeSystem(c.getSystem());
|
||||
String sn = cs != null ? cs.present() : describeSystem(c.getSystem());
|
||||
String link = getLinkForCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||
if (link != null) {
|
||||
x.ah(link).tx(sn);
|
||||
|
|
|
@ -680,7 +680,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
if (disp == null) {
|
||||
disp = getDisplayForUrl(url);
|
||||
}
|
||||
if (disp != null && !designations.containsKey(url)) {
|
||||
if (disp != null && !designations.containsKey(url) && url != null) {
|
||||
designations.put(url, disp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class FHIRToolingClientTest {
|
|||
|
||||
private void checkHeaders(Headers argumentCaptorValue) {
|
||||
getHeaders().forEach(header -> {
|
||||
System.out.println("Checking header <" + header.component1().utf8() + ", " + header.component2().utf8() + ">");
|
||||
// System.out.println("Checking header <" + header.component1().utf8() + ", " + header.component2().utf8() + ">");
|
||||
Assertions.assertEquals(argumentCaptorValue.get(header.component1().utf8()), header.component2().utf8());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -78,6 +78,10 @@ public class SimpleHTTPClient {
|
|||
throw new IOException("Invalid HTTP response "+code+" from "+source+" ("+message+") (content in "+filename+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ public class PackageClient {
|
|||
params.append("name="+name);
|
||||
}
|
||||
if (!Utilities.noString(canonical)) {
|
||||
params.append("canonical="+canonical);
|
||||
params.append("pkgcanonical="+canonical);
|
||||
}
|
||||
if (!Utilities.noString(fhirVersion)) {
|
||||
params.append("fhirversion="+fhirVersion);
|
||||
|
|
|
@ -83,7 +83,8 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
|
|||
Ontology,
|
||||
ProfileComparer,
|
||||
TerminologyEngine,
|
||||
QuestionnaireResponseValidator
|
||||
QuestionnaireResponseValidator,
|
||||
IPAValidator
|
||||
}
|
||||
|
||||
public enum IssueSeverity {
|
||||
|
|
|
@ -361,7 +361,7 @@ element__null_ = element = null: {0}
|
|||
getSliceList_should_only_be_called_when_the_element_has_slicing = getSliceList should only be called when the element has slicing
|
||||
Unable_to_resolve_name_reference__at_path_ = Unable to resolve name reference {0} at path {1}
|
||||
Details_for__matching_against_Profile_ = Details for {0} matching against Profile {1}
|
||||
Does_not_match_slice_ = Does not match slice ''{0}''
|
||||
Does_not_match_slice_ = Does not match slice ''{0}'' (discriminator: {1})
|
||||
Profile__does_not_match_for__because_of_the_following_profile_issues__ = Profile {0} does not match for {1} because of the following profile issues: {2}
|
||||
This_element_does_not_match_any_known_slice_ = This element does not match any known slice{0}
|
||||
defined_in_the_profile = defined in the profile
|
||||
|
|
|
@ -16,8 +16,8 @@ public class SimpleHTTPClientTest {
|
|||
|
||||
SimpleHTTPClient.HTTPResult res = http.get(url, "application/json");
|
||||
|
||||
System.out.println(res.getCode());
|
||||
System.out.println(new String(res.getContent(), StandardCharsets.UTF_8));
|
||||
// System.out.println(res.getCode());
|
||||
// System.out.println(new String(res.getContent(), StandardCharsets.UTF_8));
|
||||
assertTrue(res.getCode() != 400);
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ class I18nBaseTest {
|
|||
BufferedReader reader = new BufferedReader(streamReader)) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println("Searching for umlauts -> " + line);
|
||||
// System.out.println("Searching for umlauts -> " + line);
|
||||
Assertions.assertFalse(stringContainsItemFromList(line, UMLAUTS));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -35,9 +35,9 @@ public class CachingPackageClientTests {
|
|||
public void testSearch() throws IOException {
|
||||
CachingPackageClient client = new CachingPackageClient(CachingPackageClientTests.SERVER1);
|
||||
List<PackageInfo> matches = client.search("core", null, null, false);
|
||||
for (PackageInfo pi : matches) {
|
||||
System.out.println(pi.toString());
|
||||
}
|
||||
// for (PackageInfo pi : matches) {
|
||||
// System.out.println(pi.toString());
|
||||
// }
|
||||
Assertions.assertTrue(matches.size() > 0);
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,9 @@ public class CachingPackageClientTests {
|
|||
public void testVersions() throws IOException {
|
||||
CachingPackageClient client = new CachingPackageClient(CachingPackageClientTests.SERVER1);
|
||||
List<PackageInfo> matches = client.getVersions("Simplifier.Core.STU3");
|
||||
for (PackageInfo pi : matches) {
|
||||
System.out.println(pi.toString());
|
||||
}
|
||||
// for (PackageInfo pi : matches) {
|
||||
// System.out.println(pi.toString());
|
||||
// }
|
||||
Assertions.assertTrue(matches.size() > 0);
|
||||
}
|
||||
|
||||
|
@ -78,9 +78,9 @@ public class CachingPackageClientTests {
|
|||
public void testSearch2() throws IOException {
|
||||
CachingPackageClient client = new CachingPackageClient(CachingPackageClientTests.SERVER2);
|
||||
List<PackageInfo> matches = client.search("core", null, null, false);
|
||||
for (PackageInfo pi : matches) {
|
||||
System.out.println(pi.toString());
|
||||
}
|
||||
// for (PackageInfo pi : matches) {
|
||||
// System.out.println(pi.toString());
|
||||
// }
|
||||
Assertions.assertTrue(matches.size() > 0);
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,9 @@ public class CachingPackageClientTests {
|
|||
public void testVersions2A() throws IOException {
|
||||
CachingPackageClient client = new CachingPackageClient(CachingPackageClientTests.SERVER2);
|
||||
List<PackageInfo> matches = client.getVersions("hl7.fhir.us.core");
|
||||
for (PackageInfo pi : matches) {
|
||||
System.out.println(pi.toString());
|
||||
}
|
||||
// for (PackageInfo pi : matches) {
|
||||
// System.out.println(pi.toString());
|
||||
// }
|
||||
Assertions.assertTrue(matches.size() > 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class XhtmlNodeTest {
|
|||
"</xhtml:div>");
|
||||
|
||||
String output = node.getValueAsString();
|
||||
ourLog.info(output);
|
||||
// ourLog.info(output);
|
||||
|
||||
Assertions.assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><img src=\"http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png\" alt=\"Twitter Avatar\"/>@fhirabend</div>", output);
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ public class ValidatorCli {
|
|||
res.add("-version");
|
||||
res.add("4.0");
|
||||
res.add("-ig");
|
||||
res.add("hl7.fhir.uv.ips#current$connectathon-2");
|
||||
res.add("hl7.fhir.uv.ips#current");
|
||||
res.add("-profile");
|
||||
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
||||
} else if (a.startsWith("-ips$")) {
|
||||
|
|
|
@ -56,6 +56,7 @@ public class ComparisonService {
|
|||
// File htmlFile = cr.render(left, right);
|
||||
// Desktop.getDesktop().browse(htmlFile.toURI());
|
||||
// System.out.println("Done");
|
||||
// cr.getTemplates().put("CapabilityStatement", new String(context.getBinaries().get("template-comparison-CapabilityStatement.html")));
|
||||
}
|
||||
|
||||
public static void compareStructureDefinitions(String dest, ValidationEngine validator, String left, String right, StructureDefinition resLeft, StructureDefinition resRight) throws IOException, FHIRException, EOperationOutcome {
|
||||
|
@ -70,6 +71,7 @@ public class ComparisonService {
|
|||
cr.getTemplates().put("ValueSet", new String(validator.getContext().getBinaries().get("template-comparison-ValueSet.html")));
|
||||
cr.getTemplates().put("Profile", new String(validator.getContext().getBinaries().get("template-comparison-Profile.html")));
|
||||
cr.getTemplates().put("Index", new String(validator.getContext().getBinaries().get("template-comparison-index.html")));
|
||||
cr.getTemplates().put("CapabilityStatement", new String(validator.getContext().getBinaries().get("template-comparison-CapabilityStatement.html")));
|
||||
File htmlFile = cr.render(left, right);
|
||||
Desktop.getDesktop().browse(htmlFile.toURI());
|
||||
System.out.println("Done");
|
||||
|
|
|
@ -4,6 +4,9 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SystemOutLoggingService;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
|
@ -12,6 +15,7 @@ import org.hl7.fhir.r5.formats.XmlParser;
|
|||
import org.hl7.fhir.r5.model.*;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.renderers.spreadsheets.CodeSystemSpreadsheetGenerator;
|
||||
import org.hl7.fhir.r5.renderers.spreadsheets.ConceptMapSpreadsheetGenerator;
|
||||
import org.hl7.fhir.r5.renderers.spreadsheets.StructureDefinitionSpreadsheetGenerator;
|
||||
|
@ -24,8 +28,11 @@ import org.hl7.fhir.utilities.TextFile;
|
|||
import org.hl7.fhir.utilities.TimeTracker;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.validation.IgLoader;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
|
@ -39,6 +46,8 @@ import org.hl7.fhir.validation.cli.renderers.ValidationOutputRenderer;
|
|||
import org.hl7.fhir.validation.cli.utils.EngineMode;
|
||||
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
|
||||
|
||||
import lombok.val;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
@ -46,7 +55,9 @@ import java.io.PrintStream;
|
|||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ValidationService {
|
||||
|
||||
|
@ -329,6 +340,8 @@ public class ValidationService {
|
|||
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug());
|
||||
System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")");
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false);
|
||||
System.out.print(" Load R5 Extensions");
|
||||
System.out.println(" - " + ProfileUtilities.loadR5Extensions(validator.getPcm(), validator.getContext()) + " resources (" + tt.milestone() + ")");
|
||||
System.out.print(" Terminology server " + cliContext.getTxServer());
|
||||
String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
|
||||
System.out.println(" - Version " + txver + " (" + tt.milestone() + ")");
|
||||
|
@ -378,6 +391,8 @@ public class ValidationService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String determineVersion(CliContext cliContext) throws Exception {
|
||||
return determineVersion(cliContext, null);
|
||||
}
|
||||
|
|
|
@ -4012,10 +4012,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
|
||||
} else
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
|
||||
if (discriminator.isEmpty())
|
||||
if (discriminator.isEmpty()) {
|
||||
expression.append(" and $this is " + type);
|
||||
else
|
||||
} else {
|
||||
expression.append(" and " + discriminator + " is " + type);
|
||||
}
|
||||
} else if (s.getType() == DiscriminatorType.PROFILE) {
|
||||
if (criteriaElement.getType().size() == 0) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
|
||||
|
@ -4036,12 +4037,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
|
||||
}
|
||||
} else if (s.getType() == DiscriminatorType.EXISTS) {
|
||||
if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1)
|
||||
if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1) {
|
||||
expression.append(" and (" + discriminator + ".exists())");
|
||||
else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0"))
|
||||
} else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) {
|
||||
expression.append(" and (" + discriminator + ".exists().not())");
|
||||
else
|
||||
} else {
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
|
||||
}
|
||||
} else if (criteriaElement.hasFixed()) {
|
||||
buildFixedExpression(ed, expression, discriminator, criteriaElement);
|
||||
} else if (criteriaElement.hasPattern()) {
|
||||
|
@ -4072,12 +4074,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
timeTracker.fpe(t);
|
||||
ed.setUserData("slice.expression.cache", n);
|
||||
} else {
|
||||
}
|
||||
|
||||
ValidatorHostContext shc = hostContext.forSlicing();
|
||||
boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
|
||||
if (!pass) {
|
||||
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
|
||||
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName(), n.toString().substring(8).trim())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
|
||||
for (String url : shc.getSliceRecords().keySet()) {
|
||||
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer),
|
||||
context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url),
|
||||
|
@ -4089,6 +4092,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return pass;
|
||||
}
|
||||
|
||||
private boolean isBaseDefinition(String url) {
|
||||
boolean b = url.startsWith("http://hl7.org/fhir/") && !url.substring(40).contains("/");
|
||||
return b;
|
||||
}
|
||||
|
||||
private String descSD(String url) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
||||
return sd == null ? url : sd.present();
|
||||
}
|
||||
|
||||
private boolean isProfile(ElementDefinition slicer) {
|
||||
if (slicer == null || !slicer.hasSlicing()) {
|
||||
return false;
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
package org.hl7.fhir.validation.ipa;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.JsonParser;
|
||||
import org.hl7.fhir.utilities.SimpleHTTPClient;
|
||||
import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||
import org.hl7.fhir.validation.ipa.IPAValidator.ValidationNode;
|
||||
|
||||
/**
|
||||
* You give this validator three parameters:
|
||||
|
@ -16,6 +29,24 @@ import org.hl7.fhir.validation.instance.InstanceValidator;
|
|||
*/
|
||||
public class IPAValidator {
|
||||
|
||||
public class ValidationNode {
|
||||
|
||||
public ValidationNode(String string) {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getIssues() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String address;
|
||||
private String token;
|
||||
private String urn;
|
||||
|
@ -32,32 +63,39 @@ public class IPAValidator {
|
|||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getUrn() {
|
||||
return urn;
|
||||
}
|
||||
|
||||
public void setUrn(String urn) {
|
||||
this.urn = urn;
|
||||
}
|
||||
|
||||
public InstanceValidator getValidator() {
|
||||
return validator;
|
||||
}
|
||||
|
||||
public void setValidator(InstanceValidator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
List<Patient> patients = searchPatients();
|
||||
// check list of patients that have access to
|
||||
// require that at least one of the patients matches the URL
|
||||
List<Element> patients = searchPatients();
|
||||
if (patients.size() > 0) {
|
||||
|
||||
// validate all resources and links
|
||||
// validate search parameters
|
||||
// check self links
|
||||
|
@ -71,14 +109,84 @@ public class IPAValidator {
|
|||
// Observation patient+category, patient+code, patient+category+date patient+category+status, patient+code+date
|
||||
// Patient _id, identifier birthdate, family, gender, given, name, family+gender, birthdate+family, birthdate+name, gender+name
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<Patient> searchPatients() {
|
||||
private List<Element> searchPatients() {
|
||||
ValidationNode vn = new ValidationNode("Patient Search");
|
||||
log("Searching Patients");
|
||||
Element bundle = makeRequest(vn, "/Patient");
|
||||
List<Element> list = new ArrayList<>();
|
||||
if (bundle != null) {
|
||||
checkSelfLink(vn, bundle, null);
|
||||
List<Element> entries = bundle.getChildren("entry");
|
||||
int i = 0;
|
||||
for (Element entry : entries) {
|
||||
Element resource = entry.getNamedChild("resource");
|
||||
if (resource != null && resource.fhirType().equals("Patient")) {
|
||||
validator.validate(this, vn.getIssues(), "Bundle.entry["+i+"].resource", resource, "http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient");
|
||||
list.add(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (list.size() > 1) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "patient.search",
|
||||
"Multiple Patients found; check that this is an expected outcome",
|
||||
IssueSeverity.WARNING));
|
||||
} else if (list.size() == 0) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "patient.search",
|
||||
"No Patients found, unable to continue",
|
||||
IssueSeverity.ERROR));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void checkSelfLink(ValidationNode vn, Element bundle, Map<String, String> params) {
|
||||
// we check that there's a self link
|
||||
Element sl = null;
|
||||
for (Element e : bundle.getChildren("link")) {
|
||||
if ("self".equals(e.getNamedChildValue("relation"))) {
|
||||
sl = e.getNamedChild("url");
|
||||
}
|
||||
}
|
||||
if (sl == null) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, vn.getName(),
|
||||
"Self link not found in search result",
|
||||
IssueSeverity.ERROR));
|
||||
} else if (params != null) {
|
||||
// we check that all the provided params are in the self link
|
||||
}
|
||||
}
|
||||
|
||||
private Element makeRequest(ValidationNode vn, String url) {
|
||||
try {
|
||||
SimpleHTTPClient http = new SimpleHTTPClient();
|
||||
HTTPResult result = http.get(url, "application/fhir+json");
|
||||
if (result.getCode() >= 300) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request",
|
||||
"HTTP Return code is "+result.getCode()+" "+result.getMessage(),
|
||||
IssueSeverity.FATAL));
|
||||
return null;
|
||||
} else if (result.getContent() == null || result.getContent().length == 0) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request",
|
||||
"No Content Returned",
|
||||
IssueSeverity.FATAL));
|
||||
return null;
|
||||
} else {
|
||||
return new JsonParser(validator.getContext()).parse(new ByteArrayInputStream(result.getContent())).get(0).getElement();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request", e.getMessage(),
|
||||
IssueSeverity.FATAL));
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void log(String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "valueSet" :{
|
||||
"resourceType" : "ValueSet",
|
||||
"compose" : {
|
||||
"inactive" : true,
|
||||
"include" : [{
|
||||
"system" : "urn:iso:std:iso:4217"
|
||||
}]
|
||||
}
|
||||
}}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "url": "http://hl7.org/fhir/ValueSet/currencies", "version": "4.0.1"}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,11 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "urn:ietf:bcp:47",
|
||||
"code" : "fr-CA"
|
||||
}, "valueSet" :null, "lang":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"true"}####
|
||||
v: {
|
||||
"severity" : "error",
|
||||
"error" : "Attempt to use Terminology server when no Terminology server is available",
|
||||
"class" : "SERVER_ERROR"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,90 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "valueSet" :{
|
||||
"resourceType" : "ValueSet",
|
||||
"compose" : {
|
||||
"inactive" : true,
|
||||
"include" : [{
|
||||
"system" : "http://loinc.org",
|
||||
"concept" : [{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "A."
|
||||
}],
|
||||
"code" : "LA20752-4",
|
||||
"display" : "Within 24 hours"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "B."
|
||||
}],
|
||||
"code" : "LA20753-2",
|
||||
"display" : "After 24 hours but before 3 days"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "C."
|
||||
}],
|
||||
"code" : "LA20754-0",
|
||||
"display" : "Three days or later"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "D."
|
||||
}],
|
||||
"code" : "LA4489-6",
|
||||
"display" : "Unknown"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "valueSet" :{
|
||||
"resourceType" : "ValueSet",
|
||||
"compose" : {
|
||||
"include" : [{
|
||||
"system" : "http://loinc.org",
|
||||
"concept" : [{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "A."
|
||||
}],
|
||||
"code" : "LA20752-4",
|
||||
"display" : "Within 24 hours"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "B."
|
||||
}],
|
||||
"code" : "LA20753-2",
|
||||
"display" : "After 24 hours but before 3 days"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "C."
|
||||
}],
|
||||
"code" : "LA20754-0",
|
||||
"display" : "Three days or later"
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-label",
|
||||
"valueString" : "D."
|
||||
}],
|
||||
"code" : "LA4489-6",
|
||||
"display" : "Unknown"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,19 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "valueSet" :{
|
||||
"resourceType" : "ValueSet",
|
||||
"compose" : {
|
||||
"inactive" : true,
|
||||
"include" : [{
|
||||
"system" : "urn:ietf:bcp:13"
|
||||
}]
|
||||
}
|
||||
}}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "url": "http://hl7.org/fhir/ValueSet/mimetypes", "version": "4.0.1"}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
|
@ -0,0 +1,103 @@
|
|||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "valueSet" :{
|
||||
"resourceType" : "ValueSet",
|
||||
"compose" : {
|
||||
"inactive" : true,
|
||||
"include" : [{
|
||||
"system" : "http://unitsofmeasure.org",
|
||||
"concept" : [{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "second"
|
||||
}],
|
||||
"code" : "s",
|
||||
"display" : "second",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "秒"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "minute"
|
||||
}],
|
||||
"code" : "min",
|
||||
"display" : "minute",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "分钟"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "hour"
|
||||
}],
|
||||
"code" : "h",
|
||||
"display" : "hour",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "小时"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "day"
|
||||
}],
|
||||
"code" : "d",
|
||||
"display" : "day",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "天"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "week"
|
||||
}],
|
||||
"code" : "wk",
|
||||
"display" : "week",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "星期"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "month"
|
||||
}],
|
||||
"code" : "mo",
|
||||
"display" : "month",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "月"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"extension" : [{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition",
|
||||
"valueString" : "year"
|
||||
}],
|
||||
"code" : "a",
|
||||
"display" : "year",
|
||||
"designation" : [{
|
||||
"language" : "zh",
|
||||
"value" : "年"
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"hierarchical" : false, "url": "http://hl7.org/fhir/ValueSet/units-of-time", "version": "4.0.1"}####
|
||||
e: {
|
||||
"error" : "java.lang.NullPointerException"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
Loading…
Reference in New Issue