Merge remote-tracking branch 'origin/master' into do-20241202-refactor-process-tx-issues

This commit is contained in:
dotasek 2024-12-02 15:24:00 -05:00
commit 8d27b6f592
34 changed files with 963 additions and 226 deletions

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.convertors.loaders;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
@ -9,6 +10,7 @@ import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
@ -53,4 +55,52 @@ public class XVersionLoader {
throw new FHIRException("Unknown version " + version + " loading resource");
}
public static void saveXml(String version, Resource resource, OutputStream stream) throws FHIRFormatError, IOException {
if (Utilities.noString(version)) {
new org.hl7.fhir.r5.formats.XmlParser().compose(stream, resource, true);
}
switch (VersionUtilities.getMajMin(version)) {
case "1.0":
new org.hl7.fhir.dstu2.formats.XmlParser().compose(stream, VersionConvertorFactory_10_50.convertResource(resource), true);
return;
case "1.4":
new org.hl7.fhir.dstu2016may.formats.XmlParser().compose(stream, VersionConvertorFactory_14_50.convertResource(resource), true);
return;
case "3.0":
new org.hl7.fhir.dstu3.formats.XmlParser().compose(stream, VersionConvertorFactory_30_50.convertResource(resource), true);
return;
case "4.0":
new org.hl7.fhir.r4.formats.XmlParser().compose(stream, VersionConvertorFactory_40_50.convertResource(resource), true);
return;
case "5.0":
new org.hl7.fhir.r5.formats.XmlParser().compose(stream, resource, true);
return;
}
throw new FHIRException("Unknown version " + version + " loading resource");
}
public static void saveJson(String version, Resource resource, OutputStream stream) throws FHIRException, IOException {
if (Utilities.noString(version)) {
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(stream, resource);
}
switch (VersionUtilities.getMajMin(version)) {
case "1.0":
new org.hl7.fhir.dstu2.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2.formats.IParser.OutputStyle.PRETTY).compose(stream, VersionConvertorFactory_10_50.convertResource(resource));
return;
case "1.4":
new org.hl7.fhir.dstu2016may.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2016may.formats.IParser.OutputStyle.PRETTY).compose(stream, VersionConvertorFactory_14_50.convertResource(resource));
return;
case "3.0":
new org.hl7.fhir.dstu3.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu3.formats.IParser.OutputStyle.PRETTY).compose(stream, VersionConvertorFactory_30_50.convertResource(resource));
return;
case "4.0":
new org.hl7.fhir.r4.formats.JsonParser().setOutputStyle(org.hl7.fhir.r4.formats.IParser.OutputStyle.PRETTY).compose(stream, VersionConvertorFactory_40_50.convertResource(resource));
return;
case "5.0":
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(org.hl7.fhir.r5.formats.IParser.OutputStyle.PRETTY).compose(stream, resource);
return;
}
throw new FHIRException("Unknown version " + version + " loading resource");
}
}

View File

@ -29,7 +29,9 @@ package org.hl7.fhir.r4.profilemodel;
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.NotImplementedException;
import org.hl7.fhir.exceptions.DefinitionException;
@ -352,6 +354,7 @@ public class PEBuilder {
list = pu.getChildList(profile, profile.getSnapshot().getElementFirstRep());
}
if (list.size() > 0) {
Set<String> names = new HashSet<>();
int i = 0;
while (i < list.size()) {
ElementDefinition defn = list.get(i);
@ -361,7 +364,8 @@ public class PEBuilder {
// DebugUtilities.breakpoint();
i++;
} else {
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn, parent.path());
String name = uniquefy(names, defn.getName());
PEDefinitionElement pe = new PEDefinitionElement(this, name, profile, defn, parent.path());
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
pe.setMustHaveValue(definition.getMustHaveValue());
@ -376,14 +380,14 @@ public class PEBuilder {
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
StructureDefinition ext = getExtensionDefinition(list.get(i));
if (ext != null) {
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), profile, list.get(i), defn, ext, parent.path()));
res.add(new PEDefinitionExtension(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, ext, parent.path()));
} else if (isTypeSlicing(defn)) {
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
res.add(new PEDefinitionTypeSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
} else {
if (ProfileUtilities.isComplexExtension(profile) && defn.getPath().endsWith(".extension")) {
res.add(new PEDefinitionSubExtension(this, profile, list.get(i), parent.path()));
} else {
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
res.add(new PEDefinitionSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
}
}
i++;
@ -409,6 +413,18 @@ public class PEBuilder {
}
}
private String uniquefy(Set<String> names, String name) {
if (names.contains(name)) {
int i = 0;
while (names.contains(name+i)) {
i++;
}
name = name+i;
}
names.add(name);
return name;
}
protected PEDefinition makeChild(PEDefinition parent, StructureDefinition profileStructure, ElementDefinition definition) {
PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, definition, parent.path());
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {

View File

@ -42,6 +42,10 @@ public class PEDefinitionElement extends PEDefinition {
super(builder, definition.getName(), profile, definition, ppath);
}
public PEDefinitionElement(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, String ppath) {
super(builder, name, profile, definition, ppath);
}
@Override
public void listTypes(List<PEType> types) {
for (TypeRefComponent t : definition.getType()) {

View File

@ -30,15 +30,14 @@ package org.hl7.fhir.r4.profilemodel.gen;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import com.google.common.base.Strings;
import org.hl7.fhir.r4.context.IWorkerContext;
import org.hl7.fhir.r4.model.ElementDefinition;
import org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionBindingComponent;
@ -48,34 +47,34 @@ import org.hl7.fhir.r4.model.Type;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r4.profilemodel.PEBuilder;
import org.hl7.fhir.r4.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.r4.profilemodel.PEDefinition;
import org.hl7.fhir.r4.profilemodel.PEType;
import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
/**
*
*
* The easiest way to generate code is to use the FHIR Validator, which can generate java classes for profiles
* using this code. Parameters:
*
*
* -codegen -version r4 -ig hl7.fhir.dk.core#3.2.0 -profiles http://hl7.dk/fhir/core/StructureDefinition/dk-core-gln-identifier,http://hl7.dk/fhir/core/StructureDefinition/dk-core-patient -output /Users/grahamegrieve/temp/codegen -package-name org.hl7.fhir.test
*
*
* Parameter Documentation:
* -codegen: tells the validator to generate code
* -version {r4|5}: which version to generate for
* -version {r4|5}: which version to generate for
* -ig {name}: loads an IG (and it's dependencies) - see -ig documentation for the validator
* -profiles {list}: a comma separated list of profile URLs to generate code for
* -profiles {list}: a comma separated list of profile URLs to generate code for
* -output {folder}: the folder where to generate the output java class source code
* -package-name {name}: the name of the java package to generate in
*
*
* options
* -option {name}: a code generation option, one of:
*
*
* narrative: generate code for the resource narrative (recommended: don't - leave that for the native resource level)
* meta: generate code the what's in meta
* contained: generate code for contained resources
* contained: generate code for contained resources
* all-elements: generate code for all elements, not just the key elements (makes the code verbose)
*/
@ -87,12 +86,12 @@ public class PECodeGenerator {
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(new Date());
}
public enum ExtensionPolicy {
None, Complexes, Primitives;
}
private class PEGenClass {
private String name;
private String base;
@ -101,7 +100,7 @@ public class PECodeGenerator {
private boolean isResource;
private Set<String> unfixed = new HashSet<>();
private Set<String> enumNames = new HashSet<>();
private StringBuilder inits = new StringBuilder();
private StringBuilder fields = new StringBuilder();
private StringBuilder enums = new StringBuilder();
@ -114,7 +113,7 @@ public class PECodeGenerator {
public void genId() {
if (isResource) {
genField(true, "id", "String", "id", "", false, "", 0, 1, null);
genAccessors(true, false, "id", "id", "String", "", "String", "String", "Id", "Ids", false, "", false, false, null);
genAccessors(true, false, "id", "id", "String", "", "String", "String", "Id", "Ids", false, "", false, false, null);
genLoad(true, false, "id", "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, null, false);
genSave(true, false, "id", "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, false, null, false);
genClear(false, "id", "String");
@ -128,14 +127,14 @@ public class PECodeGenerator {
w(b, " */");
w(b);
}
w(b, "// Generated by the HAPI Java Profile Generator, "+genDate);
w(b);
w(b, "// Generated by the HAPI Java Profile Generator, "+genDate);
w(b);
jdoc(b, doco, 0, true);
w(b, "public class "+name+" extends PEGeneratedBase {");
w(b);
if (url != null) {
w(b, " public static final String CANONICAL_URL = \""+url+"\";");
w(b);
w(b);
}
if (enums.length() > 0) {
w(b, enums.toString());
@ -172,7 +171,7 @@ public class PECodeGenerator {
w(b, " PEInstance src = builder.buildPEInstance(CANONICAL_URL, source);");
w(b, " theThing.load(src);");
w(b, " return theThing;");
w(b, " }");
w(b, " }");
w(b);
} else {
jdoc(b, "Used when loading other models ", 2, true);
@ -181,13 +180,13 @@ public class PECodeGenerator {
w(b, " theThing.workerContext = source.getContext();");
w(b, " theThing.load(source);");
w(b, " return theThing;");
w(b, " }");
w(b, " }");
}
w(b);
w(b, " public void load(PEInstance src) {");
w(b, " clear();");
w(b, load.toString());
w(b, " }");
w(b, " }");
w(b);
if (isResource) {
@ -201,7 +200,7 @@ public class PECodeGenerator {
w(b, " public "+base+" build() {");
w(b, " "+base+" theThing = new "+base+"();");
w(b, " PEBuilder builder = new PEBuilder(workerContext, PEElementPropertiesPolicy.EXTENSION, true);");
w(b, " PEInstance tgt = builder.buildPEInstance(CANONICAL_URL, theThing);");
w(b, " PEInstance tgt = builder.buildPEInstance(CANONICAL_URL, theThing);");
w(b, " save(tgt, false);");
w(b, " return theThing;");
w(b, " }");
@ -217,21 +216,21 @@ public class PECodeGenerator {
}
w(b, " public void save(PEInstance tgt, boolean nulls) {");
w(b, save.toString());
w(b, " }");
w(b, " }");
w(b);
if (inits.length() > 0) {
w(b, " private void initFixedValues() {");
w(b, inits.toString());
w(b, " }");
w(b, " }");
w(b);
}
w(b, accessors.toString());
w(b);
w(b, " public void clear() {");
w(b, clear.toString());
w(b, " }");
w(b, " }");
w(b);
w(b, "}");
w(b, "}");
}
private String generateEnum(PEDefinition source, PEDefinition field) {
@ -241,9 +240,14 @@ public class PECodeGenerator {
org.hl7.fhir.r4.model.ValueSet vs = workerContext.fetchResource(org.hl7.fhir.r4.model.ValueSet.class, binding.getValueSet());
if (vs != null) {
ValueSetExpansionOutcome vse = workerContext.expandVS(vs, false, false);
Set<String> codes = new HashSet<>();
boolean hasDups = false;
if (vse.isOk()) {
String baseName = Utilities.nmtokenize(Utilities.singularise(vs.getName()));
String name = baseName;
if (workerContext.getResourceNames().contains(name)) {
name = name+"Type";
}
int c = 0;
while (enumNames.contains(name)) {
c++;
@ -253,26 +257,40 @@ public class PECodeGenerator {
for (int i = 0; i < vse.getValueset().getExpansion().getContains().size(); i++) {
ValueSetExpansionContainsComponent cc = vse.getValueset().getExpansion().getContains().get(i);
String code = Utilities.javaTokenize(cc.getCode(), true).toUpperCase();
if (Utilities.isInteger(code)) {
code = "C_"+code;
}
if (cc.getAbstract()) {
code = "_"+code;
}
if (codes.contains(code)) {
char sfx = 'A';
while (codes.contains(code+sfx)) {
sfx++;
}
code = code + sfx;
hasDups = true;
}
codes.add(code);
cc.setUserData("java.code", code);
w(enums, " "+code+(i < vse.getValueset().getExpansion().getContains().size() - 1 ? "," : ";")+" // \""+cc.getDisplay()+"\" = "+cc.getSystem()+"#"+cc.getCode());
}
w(enums, "");
w(enums, " public static "+name+" fromCode(String s) {");
w(enums, " switch (s) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case \""+cc.getCode()+"\": return "+cc.getUserString("java.code")+";");
if (!hasDups) {
w(enums, " public static "+name+" fromCode(String s) {");
w(enums, " switch (s) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case \""+cc.getCode()+"\": return "+cc.getUserString("java.code")+";");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public static "+name+" fromCoding(Coding c) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
if (cc.hasVersion()) {
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode()) && (!c.hasVersion() || \""+cc.getVersion()+"\".equals(c.getVersion()))) {");
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode()) && (!c.hasVersion() || \""+cc.getVersion()+"\".equals(c.getVersion()))) {");
} else {
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode())) {");
}
@ -302,16 +320,18 @@ public class PECodeGenerator {
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public String toCode() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+cc.getCode()+"\";");
if (!hasDups) {
w(enums, " public String toCode() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+cc.getCode()+"\";");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
}
w(enums, " default: return null;");
w(enums, " }");
w(enums, " }");
w(enums, "");
w(enums, " public Coding toCoding() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
@ -337,6 +357,7 @@ public class PECodeGenerator {
}
return null;
}
private void defineField(PEDefinition source, PEDefinition field) {
if (field.types().size() == 1) {
StructureDefinition sd = workerContext.fetchTypeDefinition(field.types().get(0).getUrl());
@ -377,8 +398,8 @@ public class PECodeGenerator {
if (isPrim && field.hasFixedValue()) {
genFixed(name, ptype, field.getFixedValue());
}
genAccessors(isPrim, isAbstract, name, field.name(), type, init, ptype, ltype, cname, csname, field.isList(), field.documentation(), field.hasFixedValue(), isEnum, field.definition());
genLoad(isPrim, isAbstract, name, sname, field.name(), type, init, ptype, ltype, cname, csname, field.isList(), field.hasFixedValue(), field.types().get(0), isEnum);
genAccessors(isPrim, isAbstract, name, field.name(), type, init, ptype, ltype, cname, csname, field.isList(), field.documentation(), field.hasFixedValue(), isEnum, field.definition());
genLoad(isPrim, isAbstract, name, sname, field.name(), type, init, ptype, ltype, cname, csname, field.isList(), field.hasFixedValue(), field.types().get(0), isEnum);
genSave(isPrim, isAbstract, name, sname, field.name(), type, init, ptype, ltype, cname, csname, field.isList(), field.hasFixedValue(), isExtension, field.types().get(0), isEnum);
genClear(field.isList(), name, ptype);
}
@ -386,10 +407,10 @@ public class PECodeGenerator {
// ignoring polymorphics for now
}
}
private void genClear(boolean list, String name, String ptype) {
if (list) {
w(clear, " "+name+".clear();");
w(clear, " "+name+".clear();");
} else if ("boolean".equals(ptype)) {
w(clear, " "+name+" = false;");
} else if ("int".equals(ptype)) {
@ -398,16 +419,25 @@ public class PECodeGenerator {
w(clear, " "+name+" = null;");
}
}
private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String fname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo, boolean isEnum) {
if (isList) {
w(load, " for (PEInstance item : src.children(\""+fname+"\")) {");
if ("BackboneElement".equals(type)) {
w(load, " "+name+".add(("+type+") item.asElement());");
} else if (!Strings.isNullOrEmpty(typeInfo.getUrl()) && typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(load, " "+name+".add(("+type+") item.asDataType());");
if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(load, " "+name+".add("+type+".fromSource(src.child(\""+fname+"\")));");
} else if ("BackboneElement".equals(type)) {
w(load, " "+name+".add(("+type+") item.asElement());");
} else if (isEnum) {
if ("CodeableConcept".equals(typeInfo.getName())) {
w(load, " "+name+".add("+type+".fromCodeableConcept((CodeableConcept) item.asDataType()));");
} else if ("Coding".equals(typeInfo.getName())) {
w(load, " "+name+".add("+type+".fromCoding((Coding) item.asDataType()));");
} else {
w(load, " "+name+".add("+type+".fromCode(item.asDataType().primitiveValue()));");
}
} else {
w(load, " "+name+".add("+type+".fromSource(item));");
w(load, " "+name+".add(("+type+") item.asDataType());");
}
w(load, " }");
} else if (isEnum) {
@ -418,27 +448,31 @@ public class PECodeGenerator {
w(load, " "+name+" = "+type+".fromCoding((Coding) src.child(\""+fname+"\").asDataType());");
} else {
w(load, " "+name+" = "+type+".fromCode(src.child(\""+fname+"\").asDataType().primitiveValue());");
}
w(load, " }");
}
w(load, " }");
} else if (isPrim) {
w(load, " if (src.hasChild(\""+fname+"\")) {");
if ("CodeType".equals(type)) {
// might be code or enum
// might be code or enum
w(load, " "+name+" = src.child(\""+fname+"\").asDataType().primitiveValue();");
} else {
w(load, " "+name+" = (("+type+") src.child(\""+fname+"\").asDataType()).getValue();");
}
w(load, " }");
w(load, " }");
} else if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(load, " if (src.hasChild(\""+fname+"\")) {");
w(load, " "+name+" = "+type+".fromSource(src.child(\""+fname+"\"));");
w(load, " }");
} else {
w(load, " if (src.hasChild(\""+fname+"\")) {");
w(load, " if (src.hasChild(\""+fname+"\")) {");
if ("BackboneElement".equals(type)) {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asElement();");
} else if (Utilities.existsInList(type, workerContext.getResourceNames())) {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asResource();");
} else if("Reference".equals(type)) {
w(load, " "+type+" ref = ("+type+") src.child(\""+fname+"\").asDataType();");
w(load, " if(!ref.isEmpty())");
w(load, " "+name+" = ref;");
} else {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asDataType();");
}
@ -450,10 +484,20 @@ public class PECodeGenerator {
w(save, " tgt.clear(\""+fname+"\");");
if (isList) {
w(save, " for ("+type+" item : "+name+") {");
if (isExtension && !Strings.isNullOrEmpty(typeInfo.getUrl()) && typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", item);");
} else if (isExtension) {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", item.getData());");
if (isExtension) {
if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(save, " item.save(tgt.makeChild(\""+fname+"\"), false);");
} else {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", item);");
}
} else if (isEnum) {
if ("CodeableConcept".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+fname+"\", item.toCodeableConcept());");
} else if ("Coding".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+fname+"\", item.toCoding());");
} else {
w(save, " tgt.addChild(\""+fname+"\", item.toCode());");
}
} else {
w(save, " tgt.addChild(\""+fname+"\", item);");
}
@ -466,8 +510,8 @@ public class PECodeGenerator {
w(save, " tgt.addChild(\""+fname+"\", "+name+".toCoding());");
} else {
w(save, " tgt.addChild(\""+fname+"\", "+name+".toCode());");
}
w(save, " }");
}
w(save, " }");
} else if (isPrim) {
if ("boolean".equals(ptype)) {
w(save, " if (true) { // for now, at least");
@ -479,7 +523,7 @@ public class PECodeGenerator {
if (isExtension) {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", new "+type+"("+name+"));");
} else if (Utilities.existsInList(type, "DateType", "InstantType", "DateTimeType")) {
w(save, " tgt.addChild(\""+fname+"\", new "+type+"("+name+"));");
w(save, " tgt.addChild(\""+fname+"\", new "+type+"("+name+"));");
} else {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value\", new "+type+"("+name+"));");
}
@ -511,7 +555,7 @@ public class PECodeGenerator {
if (isFixed) {
w(accessors, " public boolean has"+cname+"() {");
w(accessors, " return true;");
w(accessors, " }");
w(accessors, " }");
} else {
w(accessors, " public "+this.name+" set"+cname+"("+ptype+" value) {");
w(accessors, " this."+name+" = value;");
@ -520,13 +564,13 @@ public class PECodeGenerator {
w(accessors);
w(accessors, " public boolean has"+cname+"() {");
if ("boolean".equals(ptype)) {
w(accessors, " return true; // not "+name+" != false ?");
w(accessors, " return true; // not "+name+" != false ?");
} else if ("int".equals(ptype)) {
w(accessors, " return "+name+" != 0;");
w(accessors, " return "+name+" != 0;");
} else {
w(accessors, " return "+name+" != null;");
}
w(accessors, " }");
w(accessors, " }");
}
} else {
if (isPrim && !isList) {
@ -553,24 +597,31 @@ public class PECodeGenerator {
w(accessors, " return "+name+" != null && !"+name+".isEmpty();");
w(accessors, " }");
w(accessors);
if (!isAbstract) {
w(accessors, " public "+type+" add"+csname+"() {");
w(accessors, " "+type+" theThing = new "+type+"();");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " return theThing;");
w(accessors, " }");
w(accessors);
if (!isAbstract) {
if (!isEnum) {
w(accessors, " public "+type+" add"+csname+"() {");
w(accessors, " "+type+" theThing = new "+type+"();");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " return theThing;");
w(accessors, " }");
w(accessors);
} else {
w(accessors, " public void add"+csname+"("+type+" theThing) {");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " }");
w(accessors);
}
}
w(accessors, " public boolean has"+csname+"("+type+" item) {");
w(accessors, " return has"+cname+"() && "+name+".contains(item);");
w(accessors, " }");
w(accessors);
w(accessors);
w(accessors, " public void remove"+csname+"("+type+" item) {");
w(accessors, " if (has"+csname+"(item)) {");
w(accessors, " "+name+".remove(item);");
w(accessors, " }");
w(accessors, " }");
w(accessors);
w(accessors);
} else if (isPrim) {
if (!isFixed) {
w(accessors, " public "+this.name+" set"+cname+"("+ptype+" value) {");
@ -586,7 +637,7 @@ public class PECodeGenerator {
w(accessors, " public boolean has"+cname+"() {");
w(accessors, " return "+name+" != null && "+name+".hasValue();");
w(accessors, " }");
w(accessors);
w(accessors);
} else {
if (!isFixed) {
w(accessors, " public "+this.name+" set"+cname+"("+type+" value) {");
@ -610,7 +661,7 @@ public class PECodeGenerator {
w(fields, " @BindingStrength(\""+ed.getBinding().getStrength().toCode()+"\") @ValueSet(\""+ed.getBinding().getValueSet()+"\")");
}
if (ed.getMustSupport()) {
w(fields, " @MustSupport(true)");
w(fields, " @MustSupport(true)");
}
if (ed.hasLabel() || ed.hasDefinition()) {
String s = "";
@ -620,7 +671,7 @@ public class PECodeGenerator {
if (ed.hasDefinition()) {
s = s + " @Definition(\""+Utilities.escapeJava(ed.getDefinition())+"\")";
}
w(fields, " "+s);
w(fields, " "+s);
}
}
if (isPrim && extensionPolicy != ExtensionPolicy.Primitives && !isList) {
@ -628,7 +679,7 @@ public class PECodeGenerator {
} else if (isList) {
w(fields, " private "+ltype+" "+name+" = new ArrayList<>();"+nn+" // "+shortDoco);
} else {
w(fields, " private "+ltype+" "+name+";"+nn+" // "+shortDoco);
w(fields, " private "+ltype+" "+name+";"+nn+" // "+shortDoco);
}
w(fields, "");
}
@ -768,8 +819,9 @@ public class PECodeGenerator {
PEDefinition source = new PEBuilder(workerContext, PEElementPropertiesPolicy.EXTENSION, true).buildPEDefinition(canonical);
w(imports, "import java.util.List;");
w(imports, "import java.util.ArrayList;");
w(imports, "import javax.annotation.Nullable;");
w(imports, "import java.util.Date;\r\n");
w(imports, "import java.math.BigDecimal;");
w(imports, "import javax.annotation.Nullable;");
w(imports);
w(imports, "import org.hl7.fhir."+version+".context.IWorkerContext;");
w(imports, "import org.hl7.fhir."+version+".model.*;");
@ -785,7 +837,7 @@ public class PECodeGenerator {
w(imports, "import org.hl7.fhir."+version+".profilemodel.gen.ValueSet;");
w(imports, "import org.hl7.fhir."+version+".profilemodel.gen.MustSupport;");
w(imports, "import org.hl7.fhir."+version+".profilemodel.gen.Definition;");
PEGenClass cls = genClass(source);
StringBuilder b = new StringBuilder();
@ -810,7 +862,7 @@ public class PECodeGenerator {
w(b, pfx+" *");
}
w(b, pfx+" */");
}
}
}
private List<String> naturalLines(String line) {
@ -839,7 +891,7 @@ public class PECodeGenerator {
private void w(StringBuilder b, String line) {
b.append(line);
w(b);
w(b);
}
private PEGenClass genClass(PEDefinition source) {
@ -854,7 +906,7 @@ public class PECodeGenerator {
if (genForField(source, child)) {
cls.defineField(source, child);
}
}
}
return cls;
}

View File

@ -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.StructureDefinitionComparer.ProfileComparison;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
@ -16,16 +18,26 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent;
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer;
import org.hl7.fhir.r5.renderers.CodeSystemRenderer;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.RenderingI18nContext;
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.utilities.validation.ValidationOptions;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel;
import org.hl7.fhir.utilities.xhtml.XhtmlDocument;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class CodeSystemComparer extends CanonicalResourceComparer {
@ -628,4 +640,14 @@ public class CodeSystemComparer extends CanonicalResourceComparer {
return "CodeSystem";
}
public XhtmlNode renderUnion(CodeSystemComparison comp, String id, String prefix, String corePath) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
CodeSystemRenderer csr = new CodeSystemRenderer(new RenderingContext(session.getContextLeft(), null, new ValidationOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
return csr.buildNarrative(ResourceWrapper.forResource(csr.getContext(), comp.union));
}
public XhtmlNode renderIntersection(CodeSystemComparison comp, String id, String prefix, String corePath) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
CodeSystemRenderer csr = new CodeSystemRenderer(new RenderingContext(session.getContextLeft(), null, new ValidationOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
return csr.buildNarrative(ResourceWrapper.forResource(csr.getContext(), comp.intersection));
}
}

View File

@ -12,7 +12,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
@ -32,6 +34,7 @@ import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.Tuple;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.LiquidEngine;
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
import org.hl7.fhir.utilities.FhirPublication;
@ -109,7 +112,7 @@ public class ComparisonRenderer implements IEvaluationContext {
if (comp.fhirType().equals(name)) {
if (first) {
first = false;
b.append("<tr><td colspan=\"4\"><b>"+Utilities.pluralize(name, 2)+"</b></td></tr>\r\n");
b.append("<tr><td colspan=\"6\"><b>"+Utilities.pluralize(name, 2)+"</b></td></tr>\r\n");
}
try {
renderComparison(id, comp);
@ -143,7 +146,7 @@ public class ComparisonRenderer implements IEvaluationContext {
}
}
private void renderComparison(String id, ResourceComparison comp) throws IOException {
private void renderComparison(String id, ResourceComparison comp) throws IOException, FHIRFormatError, DefinitionException, FHIRException, EOperationOutcome {
if (comp instanceof ProfileComparison) {
renderProfile(id, (ProfileComparison) comp);
} else if (comp instanceof ValueSetComparison) {
@ -169,7 +172,7 @@ public class ComparisonRenderer implements IEvaluationContext {
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
}
private void renderCodeSystem(String id, CodeSystemComparison comp) throws IOException {
private void renderCodeSystem(String id, CodeSystemComparison comp) throws IOException, FHIRFormatError, DefinitionException, FHIRException, EOperationOutcome {
String template = templates.get("CodeSystem");
Map<String, Base> vars = new HashMap<>();
CodeSystemComparer cs = new CodeSystemComparer(session);
@ -183,17 +186,32 @@ public class ComparisonRenderer implements IEvaluationContext {
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("concepts", new StringType(new XhtmlComposer(true).compose(cs.renderConcepts(comp, "", ""))));
String cnt = processTemplate(template, "CodeSystem", vars);
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(folder, comp.getId() + "-union.json")), comp.getUnion());
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(folder, comp.getId() + "-intersection.json")), comp.getIntersection());
String union = new XhtmlComposer(true).compose(cs.renderUnion(comp, "", folder, "http://hl7.org/fhir"));
String intersection = new XhtmlComposer(true).compose(cs.renderIntersection(comp, "", folder, "http://hl7.org/fhir"));
vars.put("union", new StringType(union));
vars.put("intersection", new StringType(intersection));
template = templates.get("CodeSystem-Union");
cnt = processTemplate(template, "CodeSystem-Union", vars);
TextFile.stringToFile(cnt, file(comp.getId()+"-union.html"));
template = templates.get("CodeSystem-Intersection");
cnt = processTemplate(template, "CodeSystem-Intersection", vars);
TextFile.stringToFile(cnt, file(comp.getId()+"-intersection.html"));
}
private String file(String name) throws IOException {
return Utilities.path(folder, name);
}
private void renderValueSet(String id, ValueSetComparison comp) throws FHIRException, IOException {
private void renderValueSet(String id, ValueSetComparison comp) throws FHIRException, IOException, EOperationOutcome {
String template = templates.get("ValueSet");
Map<String, Base> vars = new HashMap<>();
ValueSetComparer cs = new ValueSetComparer(session);
@ -212,6 +230,19 @@ public class ComparisonRenderer implements IEvaluationContext {
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(folder, comp.getId() + "-union.json")), comp.getUnion());
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(folder, comp.getId() + "-intersection.json")), comp.getIntersection());
String union = new XhtmlComposer(true).compose(cs.renderUnion(comp, "", folder, "http://hl7.org/fhir"));
String intersection = new XhtmlComposer(true).compose(cs.renderIntersection(comp, "", folder, "http://hl7.org/fhir"));
vars.put("union", new StringType(union));
vars.put("intersection", new StringType(intersection));
template = templates.get("ValueSet-Union");
cnt = processTemplate(template, "ValueSet-Union", vars);
TextFile.stringToFile(cnt, file(comp.getId()+"-union.html"));
template = templates.get("ValueSet-Intersection");
cnt = processTemplate(template, "ValueSet-Intersection", vars);
TextFile.stringToFile(cnt, file(comp.getId()+"-intersection.html"));
}
private void renderProfile(String id, ProfileComparison comp) throws IOException {

View File

@ -202,7 +202,7 @@ public class ResourceComparer {
s = s + "<td><a href=\""+getId()+".html\">Failed<a></td>";
color = COLOR_ISSUE;
}
s = s + "<td>"+(e != null ? Utilities.escapeXml(e.getMessage()) : "")+"</td>";
s = s + "<td colspan=\"3\">"+(e != null ? Utilities.escapeXml(e.getMessage()) : "")+"</td>";
return "<tr style=\"background-color: "+color+"\">"+s+"</tr>\r\n";
}

View File

@ -7,6 +7,8 @@ import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.Element;
@ -16,10 +18,18 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.renderers.CodeSystemRenderer;
import org.hl7.fhir.r5.renderers.ValueSetRenderer;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.RenderingI18nContext;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
@ -165,7 +175,7 @@ public class ValueSetComparer extends CanonicalResourceComparer {
intersection.getInclude().add(csI);
StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r);
res.getIncludes().getChildren().add(sm);
def = compareDefinitions("ValueSet.compose.exclude["+right.getInclude().indexOf(r)+"]", l, r, sm, csM, csI, res) || def;
def = compareDefinitions("ValueSet.compose.include["+right.getInclude().indexOf(r)+"]", l, r, sm, csM, csI, res) || def;
}
}
for (ConceptSetComponent r : right.getInclude()) {
@ -341,7 +351,7 @@ public class ValueSetComparer extends CanonicalResourceComparer {
intersection.getFilter().add(ci);
StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r);
combined.getChildren().add(sm);
if (!compareFilters(l, r, sm, cu, ci)) {
if (compareFilters(l, r, sm, cu, ci)) {
res.updateContentState(true);
session.markChanged(r, l);
}
@ -420,7 +430,7 @@ public class ValueSetComparer extends CanonicalResourceComparer {
cu.setOp(l.getOp());
cu.setValue(l.getValue());
}
return !l.getProperty().equals(r.getProperty());
return !l.getValue().equals(r.getValue());
}
private CanonicalType findInList(List<CanonicalType> matches, CanonicalType item, List<CanonicalType> source) {
@ -904,4 +914,15 @@ public class ValueSetComparer extends CanonicalResourceComparer {
return false;
}
public XhtmlNode renderUnion(ValueSetComparison comp, String id, String prefix, String corePath) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
ValueSetRenderer vsr = new ValueSetRenderer(new RenderingContext(session.getContextLeft(), null, new ValidationOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
return vsr.buildNarrative(ResourceWrapper.forResource(vsr.getContext(), comp.union));
}
public XhtmlNode renderIntersection(ValueSetComparison comp, String id, String prefix, String corePath) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
ValueSetRenderer vsr = new ValueSetRenderer(new RenderingContext(session.getContextLeft(), null, new ValidationOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
return vsr.buildNarrative(ResourceWrapper.forResource(vsr.getContext(), comp.intersection));
}
}

View File

@ -2450,7 +2450,10 @@ public class ProfileUtilities {
}
}
}
// Before applying changes, apply them to what's in the profile
// but only if it's an extension or a resource
StructureDefinition profile = null;
boolean msg = true;
if (base.hasSliceName()) {
@ -2482,7 +2485,7 @@ public class ProfileUtilities {
msg = false;
}
}
if (profile != null) {
if (profile != null && (profile.getKind() == StructureDefinitionKind.RESOURCE || "Extension".equals(profile.getType()))) {
if (profile.getSnapshot().getElement().isEmpty()) {
throw new DefinitionException(context.formatMessage(I18nConstants.SNAPSHOT_IS_EMPTY, profile.getVersionedUrl()));
}

View File

@ -1375,7 +1375,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
try {
Parameters pIn = constructParameters(options, code);
res = validateOnServer(tc, vs, pIn, options);
res = validateOnServer2(tc, vs, pIn, options, systems);
} catch (Exception e) {
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage(), null).setTxLink(txLog == null ? null : txLog.getLastId()).setErrorClass(TerminologyServiceErrorClass.SERVER_ERROR);
}
@ -1645,7 +1645,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
txLog("$validate "+txCache.summary(code)+" for "+ txCache.summary(vs)+" on "+tc.getAddress());
try {
Parameters pIn = constructParameters(options, code);
res = validateOnServer(tc, vs, pIn, options);
res = validateOnServer2(tc, vs, pIn, options, systems);
} catch (Exception e) {
issues.clear();
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXCEPTION);
@ -1727,6 +1727,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
protected ValidationResult validateOnServer(TerminologyClientContext tc, ValueSet vs, Parameters pin, ValidationOptions options) throws FHIRException {
return validateOnServer2(tc, vs, pin, options, null);
}
protected ValidationResult validateOnServer2(TerminologyClientContext tc, ValueSet vs, Parameters pin, ValidationOptions options, Set<String> systems) throws FHIRException {
if (vs != null) {
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
@ -1737,7 +1741,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
}
addServerValidationParameters(tc, vs, pin, options);
addServerValidationParameters(tc, vs, pin, options, systems);
if (txLog != null) {
txLog.clearLastId();
@ -1755,6 +1759,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
protected void addServerValidationParameters(TerminologyClientContext terminologyClientContext, ValueSet vs, Parameters pin, ValidationOptions options) {
addServerValidationParameters(terminologyClientContext, vs, pin, options, null);
}
protected void addServerValidationParameters(TerminologyClientContext terminologyClientContext, ValueSet vs, Parameters pin, ValidationOptions options, Set<String> systems) {
boolean cache = false;
if (vs != null) {
if (terminologyClientContext != null && terminologyClientContext.isTxCaching() && terminologyClientContext.getCacheId() != null && vs.getUrl() != null && terminologyClientContext.getCached().contains(vs.getUrl()+"|"+ vs.getVersion())) {
@ -1777,6 +1785,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
cache = true;
addDependentResources(terminologyClientContext, pin, vs);
}
if (systems != null) {
for (String s : systems) {
cache = addDependentCodeSystem(terminologyClientContext, pin, s, null) || cache;
}
}
pin.addParameter().setName("cache-id").setValue(new IdType(terminologyClientManager.getCacheId()));
for (ParametersParameterComponent pp : pin.getParameter()) {
if (pp.getName().equals("profile")) {
@ -1823,13 +1836,20 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
}
}
CodeSystem cs = fetchResource(CodeSystem.class, inc.getSystem(), src);
String sys = inc.getSystem();
cache = addDependentCodeSystem(tc, pin, sys, src) || cache;
return cache;
}
public boolean addDependentCodeSystem(TerminologyClientContext tc, Parameters pin, String sys, Resource src) {
boolean cache = false;
CodeSystem cs = fetchResource(CodeSystem.class, sys, src);
if (cs != null && !hasCanonicalResource(pin, "tx-resource", cs.getVUrl()) && (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)) {
cache = checkAddToParams(tc, pin, cs) || cache;
}
for (CodeSystem supp : codeSystems.getSupplements(cs)) {
//if (supp.getContent() == CodeSystemContentMode.SUPPLEMENT && supp.getSupplements().equals(inc.getSystem())) {
assert supp.getContent() == CodeSystemContentMode.SUPPLEMENT && supp.getSupplements().equals(inc.getSystem());
assert supp.getContent() == CodeSystemContentMode.SUPPLEMENT && supp.getSupplements().equals(sys);
cache = checkAddToParams(tc, pin, supp) || cache;
//}
}

View File

@ -63,8 +63,13 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
file.println("\r\n--- "+id+" -----------------\r\nRequest: \r\n");
file.println(method+" "+url+" HTTP/1.0");
if (headers != null) {
for (String s : headers)
file.println(s);
for (String s : headers) {
if (s.startsWith("Api-Key")) {
file.println("Api-Key: xxxxxxxxxxxxxxxx");
} else {
file.println(s);
}
}
}
if (body != null) {
file.println("");

View File

@ -29,7 +29,9 @@ package org.hl7.fhir.r5.profilemodel;
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.NotImplementedException;
import org.hl7.fhir.exceptions.DefinitionException;
@ -352,6 +354,7 @@ public class PEBuilder {
list = pu.getChildList(profile, profile.getSnapshot().getElementFirstRep());
}
if (list.size() > 0) {
Set<String> names = new HashSet<>();
int i = 0;
while (i < list.size()) {
ElementDefinition defn = list.get(i);
@ -361,7 +364,8 @@ public class PEBuilder {
// DebugUtilities.breakpoint();
i++;
} else {
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn, parent.path());
String name = uniquefy(names, defn.getName());
PEDefinitionElement pe = new PEDefinitionElement(this, name, profile, defn, parent.path());
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
pe.setMustHaveValue(definition.getMustHaveValue());
@ -376,14 +380,14 @@ public class PEBuilder {
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
StructureDefinition ext = getExtensionDefinition(list.get(i));
if (ext != null) {
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), profile, list.get(i), defn, ext, parent.path()));
res.add(new PEDefinitionExtension(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, ext, parent.path()));
} else if (isTypeSlicing(defn)) {
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
res.add(new PEDefinitionTypeSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
} else {
if (ProfileUtilities.isComplexExtension(profile) && defn.getPath().endsWith(".extension")) {
res.add(new PEDefinitionSubExtension(this, profile, list.get(i), parent.path()));
} else {
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
res.add(new PEDefinitionSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
}
}
i++;
@ -409,6 +413,18 @@ public class PEBuilder {
}
}
private String uniquefy(Set<String> names, String name) {
if (names.contains(name)) {
int i = 0;
while (names.contains(name+i)) {
i++;
}
name = name+i;
}
names.add(name);
return name;
}
protected PEDefinition makeChild(PEDefinition parent, StructureDefinition profileStructure, ElementDefinition definition) {
PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, definition, parent.path());
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {

View File

@ -42,6 +42,10 @@ public class PEDefinitionElement extends PEDefinition {
super(builder, definition.getName(), profile, definition, ppath);
}
public PEDefinitionElement(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, String ppath) {
super(builder, name, profile, definition, ppath);
}
@Override
public void listTypes(List<PEType> types) {
for (TypeRefComponent t : definition.getType()) {

View File

@ -1,62 +1,28 @@
package org.hl7.fhir.r5.profilemodel.gen;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, \
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this \
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, \
this list of conditions and the following disclaimer in the documentation \
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND \
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT \
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \
POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PECodeGenerator.ExtensionPolicy;
import org.hl7.fhir.r5.profilemodel.PEDefinition;
import org.hl7.fhir.r5.profilemodel.PEType;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.profilemodel.PEDefinition;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEType;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
@ -252,6 +218,9 @@ public class PECodeGenerator {
if (vse.isOk()) {
String baseName = Utilities.nmtokenize(Utilities.singularise(vs.getName()));
String name = baseName;
if (workerContext.getResourceNames().contains(name)) {
name = name+"Type";
}
int c = 0;
while (enumNames.contains(name)) {
c++;
@ -427,8 +396,19 @@ public class PECodeGenerator {
private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String fname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo, boolean isEnum) {
if (isList) {
w(load, " for (PEInstance item : src.children(\""+fname+"\")) {");
if ("BackboneElement".equals(type)) {
if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(load, " "+name+".add("+type+".fromSource(src.child(\""+fname+"\")));");
} else if ("BackboneElement".equals(type)) {
w(load, " "+name+".add(("+type+") item.asElement());");
} else if (isEnum) {
if ("CodeableConcept".equals(typeInfo.getName())) {
w(load, " "+name+".add("+type+".fromCodeableConcept((CodeableConcept) item.asDataType()));");
} else if ("Coding".equals(typeInfo.getName())) {
w(load, " "+name+".add("+type+".fromCoding((Coding) item.asDataType()));");
} else {
w(load, " "+name+".add("+type+".fromCode(item.asDataType().primitiveValue()));");
}
} else {
w(load, " "+name+".add(("+type+") item.asDataType());");
}
@ -462,6 +442,10 @@ public class PECodeGenerator {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asElement();");
} else if (Utilities.existsInList(type, workerContext.getResourceNames())) {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asResource();");
} else if("Reference".equals(type)) {
w(load, " "+type+" ref = ("+type+") src.child(\""+fname+"\").asDataType();");
w(load, " if(!ref.isEmpty())");
w(load, " "+name+" = ref;");
} else {
w(load, " "+name+" = ("+type+") src.child(\""+fname+"\").asDataType();");
}
@ -474,7 +458,19 @@ public class PECodeGenerator {
if (isList) {
w(save, " for ("+type+" item : "+name+") {");
if (isExtension) {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", item);");
if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) {
w(save, " item.save(tgt.makeChild(\""+fname+"\"), false);");
} else {
w(save, " tgt.makeChild(\""+fname+"\").data().setProperty(\"value[x]\", item);");
}
} else if (isEnum) {
if ("CodeableConcept".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+fname+"\", item.toCodeableConcept());");
} else if ("Coding".equals(typeInfo.getName())) {
w(save, " tgt.addChild(\""+fname+"\", item.toCoding());");
} else {
w(save, " tgt.addChild(\""+fname+"\", item.toCode());");
}
} else {
w(save, " tgt.addChild(\""+fname+"\", item);");
}
@ -574,13 +570,20 @@ public class PECodeGenerator {
w(accessors, " return "+name+" != null && !"+name+".isEmpty();");
w(accessors, " }");
w(accessors);
if (!isAbstract) {
w(accessors, " public "+type+" add"+csname+"() {");
w(accessors, " "+type+" theThing = new "+type+"();");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " return theThing;");
w(accessors, " }");
w(accessors);
if (!isAbstract) {
if (!isEnum) {
w(accessors, " public "+type+" add"+csname+"() {");
w(accessors, " "+type+" theThing = new "+type+"();");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " return theThing;");
w(accessors, " }");
w(accessors);
} else {
w(accessors, " public void add"+csname+"("+type+" theThing) {");
w(accessors, " get"+cname+"().add(theThing);");
w(accessors, " }");
w(accessors);
}
}
w(accessors, " public boolean has"+csname+"("+type+" item) {");
w(accessors, " return has"+cname+"() && "+name+".contains(item);");
@ -789,8 +792,9 @@ public class PECodeGenerator {
PEDefinition source = new PEBuilder(workerContext, PEElementPropertiesPolicy.EXTENSION, true).buildPEDefinition(canonical);
w(imports, "import java.util.List;");
w(imports, "import java.util.ArrayList;");
w(imports, "import javax.annotation.Nullable;");
w(imports, "import java.util.Date;\r\n");
w(imports, "import java.math.BigDecimal;");
w(imports, "import javax.annotation.Nullable;");
w(imports);
w(imports, "import org.hl7.fhir."+version+".context.IWorkerContext;");
w(imports, "import org.hl7.fhir."+version+".model.*;");
@ -807,7 +811,7 @@ public class PECodeGenerator {
w(imports, "import org.hl7.fhir."+version+".profilemodel.gen.MustSupport;");
w(imports, "import org.hl7.fhir."+version+".profilemodel.gen.Definition;");
PEGenClass cls = genClass(source);
StringBuilder b = new StringBuilder();
w(b, "package "+pkgName+";");

View File

@ -99,7 +99,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
for (ResourceWrapper cont : dr.children("contained")) {
x.hr();
RendererFactory.factory(cont, context.forContained()).buildNarrative(status, x, cont);
RendererFactory.factory(cont, context.forContained()).setInner(true).buildNarrative(status, x, cont);
}
}

View File

@ -75,7 +75,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
first = false;
}
x.hr();
RendererFactory.factory(cont, context.forContained()).buildNarrative(status, x, cont);
RendererFactory.factory(cont, context.forContained()).setInner(true).buildNarrative(status, x, cont);
}
}
@ -565,7 +565,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
if (i.has("answerValueSet")) {
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
defn.getPieces().add(gen.new Piece(null, (context.formatPhrase(RenderingContext.QUEST_VALUE)+" "), null));
if (Utilities.noString(i.primitiveValue("answerValueSet")) && i.primitiveValue("answerValueSet").startsWith("#")) {
if (Utilities.noString(i.primitiveValue("answerValueSet")) && i.primitiveValue("answerValueSet").startsWith("#")) {
ResourceWrapper vs = q.getContained(i.primitiveValue("answerValueSet").substring(1));
if (vs == null) {
defn.getPieces().add(gen.new Piece(null, i.primitiveValue("answerValueSet"), null));

View File

@ -76,6 +76,7 @@ public class RendererFactory {
case "Patient": return new PatientRenderer(context);
case "Provenance": return new ProvenanceRenderer(context);
case "Parameters": return new ParametersRenderer(context);
case "Questionnaire": return new QuestionnaireRenderer(context);
case "QuestionnaireResponse": return new QuestionnaireResponseRenderer(context);
}
if (resource.isDirect()) {

View File

@ -51,6 +51,7 @@ public abstract class ResourceRenderer extends DataRenderer {
protected XVerExtensionManager xverManager;
protected boolean multiLangMode;
protected boolean inner;
public ResourceRenderer(RenderingContext context) {
@ -70,6 +71,15 @@ public abstract class ResourceRenderer extends DataRenderer {
return false;
}
public boolean isInner() {
return inner;
}
public ResourceRenderer setInner(boolean inner) {
this.inner = inner;
return this;
}
/**
* Just build the narrative that would go in the resource (per @renderResource()), but don't put it in the resource
* @param dr
@ -837,9 +847,9 @@ public abstract class ResourceRenderer extends DataRenderer {
XhtmlNode p = x.para().attribute("class", "res-header-id");
String ft = context.getTranslatedCode(r.fhirType(), "http://hl7.org/fhir/fhir-types");
if (desc == null) {
p.b().tx(context.formatPhrase(context.isTechnicalMode() ? RenderingContext.PROF_DRIV_GEN_NARR_TECH : RenderingContext.PROF_DRIV_GEN_NARR, ft, ""));
p.b().tx(context.formatPhrase(context.isTechnicalMode() && !isInner() ? RenderingContext.PROF_DRIV_GEN_NARR_TECH : RenderingContext.PROF_DRIV_GEN_NARR, ft, ""));
} else {
p.b().tx(context.formatPhrase(context.isTechnicalMode() ? RenderingContext.PROF_DRIV_GEN_NARR_TECH : RenderingContext.PROF_DRIV_GEN_NARR, ft, desc));
p.b().tx(context.formatPhrase(context.isTechnicalMode() && !isInner() ? RenderingContext.PROF_DRIV_GEN_NARR_TECH : RenderingContext.PROF_DRIV_GEN_NARR, ft, desc));
}
// first thing we do is lay down the resource anchors.
@ -1464,7 +1474,7 @@ public abstract class ResourceRenderer extends DataRenderer {
context.addAnchor(id);
x.an(context.prefixAnchor(id));
}
RendererFactory.factory(c, context.forContained()).buildNarrative(status, x, c);
RendererFactory.factory(c, context.forContained()).setInner(true).buildNarrative(status, x, c);
}
}

View File

@ -256,7 +256,7 @@ public class ResourceWrapperModel extends ResourceWrapper {
}
public String getWebPath() {
return null;
return model.getWebPath();
}
public String getCodeSystemUri() {

View File

@ -320,15 +320,24 @@ public class TerminologyClientManager {
serverList = decideWhichServer(s);
// testing support
try {
serverList.replace("tx.fhir.org", new URL(getMasterClient().getAddress()).getHost());
serverList.replace("tx.fhir.org", host());
} catch (MalformedURLException e) {
}
resMap.put(s, serverList);
// resMap.put(s, serverList);
save();
}
return serverList;
}
private String host() throws MalformedURLException {
URL url = new URL(getMasterClient().getAddress());
if (url.getPort() > 0) {
return url.getHost()+":"+url.getPort();
} else {
return url.getHost();
}
}
private ServerOptionList decideWhichServer(String url) {
if (IGNORE_TX_REGISTRY || !useEcosystem) {
return new ServerOptionList(getMasterClient().getAddress());
@ -545,7 +554,7 @@ public class TerminologyClientManager {
}
if (server.contains("://tx.fhir.org")) {
try {
server = server.replace("tx.fhir.org", new URL(getMasterClient().getAddress()).getHost());
server = server.replace("tx.fhir.org", host());
} catch (MalformedURLException e) {
}
}
@ -627,7 +636,7 @@ public class TerminologyClientManager {
}
if (server.contains("://tx.fhir.org")) {
try {
server = server.replace("tx.fhir.org", new URL(getMasterClient().getAddress()).getHost());
server = server.replace("tx.fhir.org", host());
} catch (MalformedURLException e) {
}
}

View File

@ -0,0 +1,128 @@
package org.hl7.fhir.r5.utils;
import java.util.List;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.model.JsonArray;
import org.hl7.fhir.utilities.json.model.JsonElement;
// this class exists to allow the Liquid Engine to be used against raw JSON
public class BaseCSVWrapper extends Base {
private static final long serialVersionUID = 1L;
private List<String> columns;
private List<String> values;
private List<List<String>> rows;
private String value;
private BaseCSVWrapper() {
super();
}
public static BaseCSVWrapper forRows(List<String> columns, List<List<String>> rows) {
BaseCSVWrapper self = new BaseCSVWrapper();
self.columns = columns;
self.rows = rows;
return self;
}
public static BaseCSVWrapper forRow(List<String> columns, List<String> values) {
BaseCSVWrapper self = new BaseCSVWrapper();
self.columns = columns;
self.values = values;
return self;
}
public static BaseCSVWrapper forCell(String value) {
BaseCSVWrapper self = new BaseCSVWrapper();
self.value = value;
return self;
}
@Override
public String fhirType() {
if (values != null || rows != null) {
return "Object";
} else if (Utilities.existsInList(value, "true", "false")) {
return "boolean";
} else if (Utilities.isInteger(value)) {
return "integer";
} else if (Utilities.isDecimal(value, true)) {
return "decimal";
} else if (Utilities.isAbsoluteUrl(value)) {
return "url";
} else {
return "string";
}
}
@Override
public String getIdBase() {
if (columns == null) {
return null;
}
int i = columns.indexOf("id");
if (i > -1) {
return values.get(i);
} else {
return null;
}
}
@Override
public void setIdBase(String value) {
throw new Error("BaseCSVWrapper is read only");
}
@Override
public Base copy() {
throw new Error("BaseCSVWrapper is read only");
}
@Override
public FhirPublication getFHIRPublicationVersion() {
return FhirPublication.R5;
}
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
if (rows != null && "rows".equals(name)) {
Base[] l = new Base[rows.size()];
for (int i = 0; i < rows.size(); i++) {
l[i] = BaseCSVWrapper.forRow(columns, rows.get(i));
}
return l;
}
if (values != null) {
int i = columns.indexOf(name);
if (i > -1) {
Base[] l = new Base[1];
l[0] = BaseCSVWrapper.forCell(values.get(i));
return l;
}
}
return super.getProperty(hash, name, checkValid);
}
@Override
public String toString() {
return value;
}
@Override
public boolean isPrimitive() {
return value != null;
}
@Override
public String primitiveValue() {
return value;
}
}

View File

@ -0,0 +1,87 @@
package org.hl7.fhir.r5.utils;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.json.model.JsonArray;
import org.hl7.fhir.utilities.json.model.JsonElement;
// this class exists to allow the Liquid Engine to be used against raw JSON
public class BaseJsonWrapper extends Base {
private static final long serialVersionUID = 1L;
private JsonElement j;
public BaseJsonWrapper(JsonElement j) {
super();
this.j = j;
}
@Override
public String fhirType() {
switch (j.type()) {
case BOOLEAN: return "boolean";
case NUMBER: return "decimal";
case OBJECT: return "Object";
case STRING: return "string";
default:
throw new Error("Shouldn't get here");
}
}
@Override
public String getIdBase() {
if (j.isJsonObject()) {
return j.asJsonObject().asString("id");
} else {
return null;
}
}
@Override
public void setIdBase(String value) {
throw new Error("BaseJsonWrapper is read only");
}
@Override
public Base copy() {
throw new Error("BaseJsonWrapper is read only");
}
@Override
public FhirPublication getFHIRPublicationVersion() {
return FhirPublication.R5;
}
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
if (j.isJsonObject() && j.asJsonObject().has(name)) {
JsonElement e = j.asJsonObject().get(name);
if (e.isJsonArray()) {
JsonArray a = e.asJsonArray();
Base[] l = new Base[a.size()];
for (int i = 0; i < a.size(); i++) {
l[i] = new BaseJsonWrapper(a.get(i));
}
return l;
} else {
Base[] l = new Base[1];
l[0] = new BaseJsonWrapper(e);
return l;
}
} else {
return super.getProperty(hash, name, checkValid);
}
}
@Override
public String toString() {
if (j.isJsonPrimitive()) {
return j.asString();
} else {
return super.toString();
}
}
}

View File

@ -49,7 +49,9 @@ import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Tuple;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -68,7 +70,8 @@ public class LiquidEngine implements IEvaluationContext {
private FHIRPathEngine engine;
private ILiquidEngineIncludeResolver includeResolver;
private ILiquidRenderingSupport renderingSupport;
private MarkDownProcessor processor = new MarkDownProcessor(Dialect.COMMON_MARK);
private class LiquidEngineContext {
private Object externalContext;
private Map<String, Base> loopVars = new HashMap<>();
@ -162,12 +165,24 @@ public class LiquidEngine implements IEvaluationContext {
}
private enum LiquidFilter {
PREPEND;
PREPEND,
MARKDOWNIFY,
UPCASE,
DOWNCASE;
public static LiquidFilter fromCode(String code) {
if ("prepend".equals(code)) {
return PREPEND;
}
if ("markdownify".equals(code)) {
return MARKDOWNIFY;
}
if ("upcase".equals(code)) {
return UPCASE;
}
if ("downcase".equals(code)) {
return DOWNCASE;
}
return null;
}
}
@ -221,12 +236,25 @@ public class LiquidEngine implements IEvaluationContext {
} else switch (i.filter) {
case PREPEND:
t = stmtToString(ctxt, engine.evaluate(ctxt, resource, resource, resource, i.expression)) + t;
break;
case MARKDOWNIFY:
t = processMarkdown(t);
break;
case UPCASE:
t = t.toUpperCase();
break;
case DOWNCASE:
t = t.toLowerCase();
break;
}
}
b.append(t);
}
private String processMarkdown(String t) {
return processor.process(t, "liquid");
}
private String stmtToString(LiquidEngineContext ctxt, List<Base> items) {
StringBuilder b = new StringBuilder();
boolean first = true;
@ -489,6 +517,9 @@ public class LiquidEngine implements IEvaluationContext {
public LiquidParser(String source) {
this.source = source;
if (source == null) {
throw new FHIRException("No Liquid source to parse");
}
cursor = 0;
}

View File

@ -32,13 +32,13 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
public class BaseWorkerContextTests {
@ -374,7 +374,7 @@ public class BaseWorkerContextTests {
TerminologyClientContext terminologyClientContext = context.getTxClientManager().getMaster();
Mockito.doReturn(createdValidationResult).when(context).validateOnServer(terminologyClientContext, valueSet, pIn, validationOptions);
Mockito.doReturn(createdValidationResult).when(context).validateOnServer2(same(terminologyClientContext), same(valueSet), same(pIn), same(validationOptions), eq(Collections.emptySet()));
ValidationContextCarrier ctxt = mock(ValidationContextCarrier.class);
@ -418,12 +418,12 @@ public class BaseWorkerContextTests {
Mockito.verify(valueSetCheckerSimple).validateCode("CodeableConcept", codeableConcept);
Mockito.verify(terminologyCache).cacheValidation(eq(cacheToken), same(createdValidationResult), eq(false));
Mockito.verify(context, times(0)).validateOnServer(any(), any(), any(), any());
Mockito.verify(context, times(0)).validateOnServer2(any(), any(), any(), any(), any());
}
@Test
public void testValidateCodableConceptWithServer() throws IOException {
public void testValidateCodeableConceptWithServer() throws IOException {
CodeableConcept codeableConcept = new CodeableConcept();
ValueSet valueSet = new ValueSet();
@ -433,7 +433,7 @@ public class BaseWorkerContextTests {
TerminologyClientContext terminologyClientContext = context.getTxClientManager().getMaster();
Mockito.doReturn(createdValidationResult).when(context).validateOnServer(terminologyClientContext, valueSet, pIn, validationOptions);
Mockito.doReturn(createdValidationResult).when(context).validateOnServer2(same(terminologyClientContext), same(valueSet), same(pIn),same(validationOptions), eq(Collections.emptySet()));
Mockito.doReturn(cacheToken).when(terminologyCache).generateValidationToken(validationOptions, codeableConcept, valueSet, expParameters);
@ -443,7 +443,7 @@ public class BaseWorkerContextTests {
Mockito.verify(valueSetCheckerSimple, times(0)).validateCode("CodeableConcept", codeableConcept);
Mockito.verify(terminologyCache).cacheValidation(eq(cacheToken), same(createdValidationResult), eq(true));
Mockito.verify(context).validateOnServer(terminologyClientContext, valueSet, pIn, validationOptions);
Mockito.verify(context).validateOnServer2(same(terminologyClientContext), same(valueSet), same(pIn), same(validationOptions), eq(Collections.emptySet()));
}
@Test

View File

@ -115,6 +115,7 @@ public class SnapShotGenerationTests {
private StructureDefinition expected;
private StructureDefinition output;
public AllowUnknownProfile allow;
private boolean json;
public TestDetails(Element test) {
super();
@ -202,8 +203,14 @@ public class SnapShotGenerationTests {
source = (StructureDefinition) new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", id + "-input.json"));
else
source = (StructureDefinition) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", id + "-input.xml"));
if (!fail)
expected = (StructureDefinition) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", id + "-expected.xml"));
if (!fail) {
if (TestingUtilities.findTestResource("r5", "snapshot-generation", id + "-expected.json")) {
json = true;
expected = (StructureDefinition) new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", id + "-expected.json"));
} else {
expected = (StructureDefinition) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", id + "-expected.xml"));
}
}
if (!Utilities.noString(include))
included.add((StructureDefinition) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", include + ".xml")));
if (!Utilities.noString(register)) {
@ -589,12 +596,16 @@ public class SnapShotGenerationTests {
if (!fail) {
test.output = output;
TestingUtilities.getSharedWorkerContext().cacheResource(output);
File dst = ManagedFileAccess.file(TestingUtilities.tempFile("snapshot", test.getId() + "-expected.xml"));
if (dst.exists())
File dst = ManagedFileAccess.file(TestingUtilities.tempFile("snapshot", test.getId() + "-expected" + (test.json ? ".json" : ".xml")));
if (dst.exists()) {
dst.delete();
}
// IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", test.getId() + "-expected.xml"), ManagedFileAccess.outStream(dst));
String actualFilePath = TestingUtilities.tempFile("snapshot", test.getId() + "-expected.xml");
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(actualFilePath), output);
if (test.json) {
new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(dst.getAbsolutePath()), output);
} else {
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(dst.getAbsolutePath()), output);
}
StructureDefinition t1 = test.expected.copy();
t1.setText(null);
StructureDefinition t2 = test.output.copy();

View File

@ -0,0 +1,130 @@
package org.hl7.fhir.r5.utils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
import org.hl7.fhir.utilities.json.JsonException;
import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.json.parser.JsonParser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class LiquidJsonTest implements IEvaluationContext {
private IWorkerContext ctxt;
private ContextUtilities cu;
private ProfileUtilities pu;
@Test
void testHistory() throws JsonException, IOException {
init();
JsonObject json = JsonParser.parseObject(TestingUtilities.loadTestResource("r5", "liquid-json", "history.json"));
LiquidEngine liquid = new LiquidEngine(ctxt, this);
LiquidDocument template = liquid.parse(TestingUtilities.loadTestResource("r5", "liquid-json", "history.liquid"), null);
BaseJsonWrapper base = new BaseJsonWrapper(json);
String s = liquid.evaluate(template, base, this).trim();
String expected = TestingUtilities.loadTestResource("r5", "liquid-json", "history.html").trim();
System.out.println(s);
Assertions.assertEquals(expected, s);
}
@Test
void testTestCases() throws JsonException, IOException {
init();
JsonObject json = JsonParser.parseObject(TestingUtilities.loadTestResource("r5", "liquid-json", "test-cases.json"));
LiquidEngine liquid = new LiquidEngine(ctxt, this);
LiquidDocument template = liquid.parse(TestingUtilities.loadTestResource("r5", "liquid-json", "test-cases.liquid"), null);
BaseJsonWrapper base = new BaseJsonWrapper(json);
String s = liquid.evaluate(template, base, this).trim();
String expected = TestingUtilities.loadTestResource("r5", "liquid-json", "test-cases.html").trim();
System.out.println(s);
Assertions.assertEquals(expected, s);
}
public void init() {
if (pu == null) {
ctxt = TestingUtilities.getSharedWorkerContext();
cu = new ContextUtilities(ctxt);
pu = new ProfileUtilities(ctxt, null, cu);
}
}
@Override
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return new ArrayList<Base>();
}
@Override
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name,
boolean explicitConstant) throws PathEngineException {
return null;
}
@Override
public boolean log(String argument, List<Base> focus) {
// TODO Auto-generated method stub
return false;
}
@Override
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
// TODO Auto-generated method stub
return null;
}
@Override
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus,
List<TypeDetails> parameters) throws PathEngineException {
// TODO Auto-generated method stub
return null;
}
@Override
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName,
List<List<Base>> parameters) {
// TODO Auto-generated method stub
return null;
}
@Override
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext)
throws FHIRException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url)
throws FHIRException {
// TODO Auto-generated method stub
return false;
}
@Override
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean paramIsType(String name, int index) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -628,9 +628,11 @@ public class Utilities {
public static String padRight(String src, char c, int len) {
StringBuilder s = new StringBuilder();
s.append(src);
for (int i = 0; i < len - src.length(); i++)
s.append(c);
if (src != null) {
s.append(src);
for (int i = 0; i < len - src.length(); i++)
s.append(c);
}
return s.toString();
}

View File

@ -178,8 +178,9 @@ public class HierarchicalTableGenerator {
return style;
}
public void setTag(String tag) {
public Piece setTag(String tag) {
this.tag = tag;
return this;
}
public Piece setText(String text) {

View File

@ -56,6 +56,7 @@ public class TxTester {
public String describe();
public Resource loadResource(String filename) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException;
public byte[] loadContent(String filename) throws FileNotFoundException, IOException;
public boolean hasContent(String filename) throws IOException;
}
private String server;
@ -172,7 +173,16 @@ public class TxTester {
}
private String loadVersion() throws JsonException, IOException {
return processHistoryMarkdown(loader.loadContent("history.md"));
if (loader.hasContent("history.json")) {
return readHistory(loader.loadContent("history.json"));
} else {
return processHistoryMarkdown(loader.loadContent("history.md"));
}
}
private String readHistory(byte[] content) throws JsonException, IOException {
JsonObject json = JsonParser.parseObject(content);
return json.getJsonObjects("versions").get(0).asString("version");
}
public static String processHistoryMarkdown(byte[] content) throws IOException {
@ -650,6 +660,11 @@ public class TxTester {
public byte[] loadContent(String filename) throws FileNotFoundException, IOException {
return TextFile.fileToBytes(Utilities.path(folder, filename));
}
@Override
public boolean hasContent(String filename) throws IOException {
return new File(Utilities.path(folder, filename)).exists();
}
}
}

View File

@ -25,6 +25,7 @@ import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
@ -100,9 +101,10 @@ public class SnapShotGenerationXTests {
private List<Rule> rules = new ArrayList<>();
private StructureDefinition source;
private StructureDefinition included;
private List<StructureDefinition> included = new ArrayList<StructureDefinition>();
private StructureDefinition expected;
private StructureDefinition output;
public boolean outputIsJson;
public TestDetails(Element test) {
super();
@ -144,7 +146,7 @@ public class SnapShotGenerationXTests {
return fail;
}
public StructureDefinition getIncluded() {
public List<StructureDefinition> getIncluded() {
return included;
}
@ -181,15 +183,22 @@ public class SnapShotGenerationXTests {
source = (StructureDefinition) XVersionLoader.loadJson(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-input.json"));
else
source = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-input.xml"));
if (!fail)
expected = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-output.xml"));
if (!fail) {
if (TestingUtilities.findTestResource("rX", "snapshot-generation", id + "-output.json")) {
outputIsJson = true;
expected = (StructureDefinition) XVersionLoader.loadJson(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-output.json"));
} else
expected = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", id + "-output.xml"));
}
if (!Utilities.noString(include))
included = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", include + ".xml"));
included.add((StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", include + ".xml")));
if (!Utilities.noString(register)) {
if (TestingUtilities.findTestResource("rX", "snapshot-generation", register + ".xml")) {
included = (StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", register + ".xml"));
} else {
included = (StructureDefinition) XVersionLoader.loadJson(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", register + ".json"));
for (String r : register.split("\\,")) {
if (TestingUtilities.findTestResource("rX", "snapshot-generation", r + ".xml")) {
included.add((StructureDefinition) XVersionLoader.loadXml(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", r + ".xml")));
} else {
included.add((StructureDefinition) XVersionLoader.loadJson(version, TestingUtilities.loadTestResourceStream("rX", "snapshot-generation", r + ".json")));
}
}
}
}
@ -314,7 +323,7 @@ public class SnapShotGenerationXTests {
else
return td.getOutput();
case INCLUDE:
return td.getIncluded();
return td.getIncluded().get(0);
default:
throw new FHIRException("Not done yet");
}
@ -394,8 +403,11 @@ public class SnapShotGenerationXTests {
for (TestDetails t : tests) {
if (t.expected != null && url.equals(t.expected.getUrl()))
return t.expected;
if (t.included != null && url.equals(t.included.getUrl()))
return t.included;
for (StructureDefinition sd : t.included) {
if (url.equals(sd.getUrl())) {
return sd;
}
}
}
return null;
}
@ -492,23 +504,26 @@ public class SnapShotGenerationXTests {
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
ProfileUtilities pu = new ProfileUtilities(UtilitiesXTests.context(version), messages, null);
pu.setNewSlicingProcessing(true);
pu.setIds(test.included, false);
pu.setAllowUnknownProfile(AllowUnknownProfile.ALL_TYPES);
StructureDefinition base = UtilitiesXTests.context(version).fetchResource(StructureDefinition.class, test.included.getBaseDefinition());
if (base != null) {
pu.generateSnapshot(base, test.included, test.included.getUrl(), "http://test.org/profile", test.included.getName());
}
if (!UtilitiesXTests.context(version).hasResource(StructureDefinition.class, test.included.getUrl()))
UtilitiesXTests.context(version).cacheResource(test.included);
int ec = 0;
for (ValidationMessage vm : messages) {
if (vm.getLevel() == IssueSeverity.ERROR) {
System.out.println(vm.summary());
ec++;
for (StructureDefinition sd : test.included) {
pu.setIds(sd, false);
pu.setAllowUnknownProfile(AllowUnknownProfile.ALL_TYPES);
StructureDefinition base = UtilitiesXTests.context(version).fetchResource(StructureDefinition.class, sd.getBaseDefinition());
if (base != null) {
pu.generateSnapshot(base, sd, sd.getUrl(), "http://test.org/profile", sd.getName());
}
if (!UtilitiesXTests.context(version).hasResource(StructureDefinition.class, sd.getUrl()))
UtilitiesXTests.context(version).cacheResource(sd);
int ec = 0;
for (ValidationMessage vm : messages) {
if (vm.getLevel() == IssueSeverity.ERROR) {
System.out.println(vm.summary());
ec++;
}
}
if (ec > 0) {
throw new FHIRException("register gen failed: " + messages.toString());
}
}
if (ec > 0)
throw new FHIRException("register gen failed: " + messages.toString());
}
StructureDefinition base = getSD(test.getSource().getBaseDefinition());
if (!base.getUrl().equals(test.getSource().getBaseDefinition()))
@ -553,10 +568,19 @@ public class SnapShotGenerationXTests {
if (!fail) {
test.output = output;
UtilitiesXTests.context(version).cacheResource(output);
File dst = ManagedFileAccess.file(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output.xml"));
File dst = ManagedFileAccess.file(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output" + (test.outputIsJson ? ".json" : ".xml")));
if (dst.exists())
dst.delete();
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-output.xml")), output);
if (test.outputIsJson) {
XVersionLoader.saveJson(version, output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
} else {
XVersionLoader.saveXml(version, output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
}
if (test.outputIsJson) {
XVersionLoader.saveJson(version, test.expected, ManagedFileAccess.outStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-expected" + (test.outputIsJson ? ".json" : ".xml"))));
} else {
XVersionLoader.saveXml(version, test.expected, ManagedFileAccess.outStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-expected" + (test.outputIsJson ? ".json" : ".xml"))));
}
StructureDefinition t1 = test.expected.copy();
t1.setText(null);
StructureDefinition t2 = test.output.copy();
@ -572,7 +596,6 @@ public class SnapShotGenerationXTests {
return path;
}
private StructureDefinition getSD(String url) throws DefinitionException, FHIRException, IOException {
StructureDefinition sd = context.getByUrl(url);
if (sd == null)

View File

@ -147,4 +147,9 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader {
public byte[] loadContent(String filename) throws FileNotFoundException, IOException {
return TestingUtilities.loadTestResourceBytes("tx", filename);
}
@Override
public boolean hasContent(String filename) throws IOException {
return TestingUtilities.findTestResource("tx", filename);
}
}

View File

@ -188,4 +188,11 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
public byte[] loadContent(String filename) throws FileNotFoundException, IOException {
return TestingUtilities.loadTestResourceBytes("tx", filename);
}
@Override
public boolean hasContent(String filename) throws IOException {
return TestingUtilities.findTestResource("tx", filename);
}
}

View File

@ -174,4 +174,9 @@ public class OntoserverTests implements ITxTesterLoader {
public byte[] loadContent(String filename) throws FileNotFoundException, IOException {
return TestingUtilities.loadTestResourceBytes("tx", filename);
}
@Override
public boolean hasContent(String filename) throws IOException {
return TestingUtilities.findTestResource("tx", filename);
}
}

View File

@ -0,0 +1,24 @@
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://fhir.de/CodeSystem/dkgev/Fachabteilungsschluessel-erweitert",
"code" : "3600"
}, "valueSet" :null, "langs":"en-US", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Intensivmedizin",
"code" : "3600",
"system" : "http://fhir.de/CodeSystem/dkgev/Fachabteilungsschluessel-erweitert",
"version" : "1.5.0",
"server" : "http://tx-dev.fhir.org/r5",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------