Merge branch 'master' of https://github.com/hapifhir/org.hl7.fhir.core
This commit is contained in:
commit
b5602e79fd
|
@ -1,7 +1,27 @@
|
|||
## Validator Changes
|
||||
|
||||
* no changes
|
||||
* fix NPE in validator around Extension context
|
||||
* Handle secondary terminology server errors properly
|
||||
* Fix questionnaire response status checking
|
||||
* Add versions to message about multiple matching profiles
|
||||
* hide API-Key from appearing on the tx log
|
||||
* Add supplements for used systems as well as for value set systems when validating on server
|
||||
* fix missing port from server when doing tx-registry redirections
|
||||
|
||||
## Other code changes
|
||||
|
||||
* no changes
|
||||
* New release of pubpack
|
||||
* Fix r4b liquid tests
|
||||
* Refactor Liquid engine and add support for forLoop and capture
|
||||
* Add support for liquid on csv files
|
||||
* Add support for using Liquid on plain JSON directly and add support for markdownify filter
|
||||
* Many improvements to Profile Code Generation
|
||||
* Start working on using new IG infrastructure for Tx tests
|
||||
* Questionnaire rendering improvements
|
||||
* Merge Functionality for CapabilityStatement.import
|
||||
* Do not use metadata from data type profiles on elements when generating snapshots
|
||||
* Fix presentation issues and union and intersection links in previous version comparison
|
||||
* Fix filter comparison logic when comparing valuesets
|
||||
* Fix version issues in snapshot generation tests
|
||||
* Eliminate id from snapshot generation test case comparison
|
||||
* Change rules around stripping extensions when generating snapshots
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -439,7 +439,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
|
|||
try {
|
||||
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
|
||||
} catch (Exception e) {
|
||||
handleException("An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException("An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -714,7 +714,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
|
|||
try {
|
||||
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
|
||||
} catch (Exception e) {
|
||||
handleException("An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException("An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
|
|||
try {
|
||||
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
|
||||
} catch (Exception e) {
|
||||
handleException("An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException("An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -383,7 +383,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
|
|||
try {
|
||||
feed = client.issueGetFeedRequest(new URI(url), withVer(getPreferredResourceFormat(), "4.0"), timeoutLong);
|
||||
} catch (Exception e) {
|
||||
handleException(0, "An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException(0, "An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hl7.fhir.r4.utils.client.EFhirClientException;
|
|||
import org.hl7.fhir.r4.utils.client.ResourceFormat;
|
||||
import org.hl7.fhir.utilities.MimeType;
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.http.*;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;
|
||||
|
||||
|
@ -179,7 +180,11 @@ public class FhirRequestBuilder {
|
|||
boolean ok = code >= 200 && code < 300;
|
||||
if (response.getContent() == null) {
|
||||
if (!ok) {
|
||||
throw new EFhirClientException(response.getMessage());
|
||||
if (Utilities.noString(response.getMessage())) {
|
||||
throw new EFhirClientException(response.getMessagefromCode());
|
||||
} else {
|
||||
throw new EFhirClientException(response.getMessage());
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -399,7 +399,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient{
|
|||
try {
|
||||
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
|
||||
} catch (Exception e) {
|
||||
handleException("An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException("An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hl7.fhir.r4b.utils.ResourceUtilities;
|
|||
import org.hl7.fhir.r4b.utils.client.EFhirClientException;
|
||||
import org.hl7.fhir.r4b.utils.client.ResourceFormat;
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.http.*;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;
|
||||
|
||||
|
@ -174,7 +175,11 @@ public class FhirRequestBuilder {
|
|||
boolean ok = code >= 200 && code < 300;
|
||||
if (response.getContent() == null) {
|
||||
if (!ok) {
|
||||
throw new EFhirClientException(response.getMessage());
|
||||
if (Utilities.noString(response.getMessage())) {
|
||||
throw new EFhirClientException(response.getMessagefromCode());
|
||||
} else {
|
||||
throw new EFhirClientException(response.getMessage());
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class LiquidEngineTests implements ILiquidEngineIncludeResolver {
|
|||
|
||||
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
|
||||
testdoc = (JsonObject) new com.google.gson.JsonParser()
|
||||
.parse(TestingUtilities.loadTestResource("r5", "liquid", "liquid-tests.json"));
|
||||
.parse(TestingUtilities.loadTestResource("r4b", "liquid", "liquid-tests.json"));
|
||||
JsonArray tests = testdoc.getAsJsonArray("tests");
|
||||
List<Arguments> objects = new ArrayList<>();
|
||||
for (JsonElement n : tests) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
@ -28,12 +30,13 @@ 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.liquid.LiquidEngine;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.LiquidDocument;
|
||||
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.LiquidEngine;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -794,6 +794,19 @@ public class ProfileUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < derived.getSnapshot().getElement().size(); i++) {
|
||||
ElementDefinition ed = derived.getSnapshot().getElement().get(i);
|
||||
if (ed.getType().size() > 1) {
|
||||
List<TypeRefComponent> toRemove = new ArrayList<ElementDefinition.TypeRefComponent>();
|
||||
for (TypeRefComponent tr : ed.getType()) {
|
||||
ElementDefinition typeSlice = findTypeSlice(derived.getSnapshot().getElement(), i, ed.getPath(), tr.getWorkingCode());
|
||||
if (typeSlice != null && typeSlice.prohibited()) {
|
||||
toRemove.add(tr);
|
||||
}
|
||||
}
|
||||
ed.getType().removeAll(toRemove);
|
||||
}
|
||||
}
|
||||
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
|
||||
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
|
||||
mappingDetails.update();
|
||||
|
@ -992,6 +1005,34 @@ public class ProfileUtilities {
|
|||
}
|
||||
|
||||
|
||||
private ElementDefinition findTypeSlice(List<ElementDefinition> list, int i, String path, String typeCode) {
|
||||
for (int j = i+1; j < list.size(); j++) {
|
||||
ElementDefinition ed = list.get(j);
|
||||
if (pathMatches(path, ed) && typeMatches(ed, typeCode)) {
|
||||
return ed;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean pathMatches(String path, ElementDefinition ed) {
|
||||
String p = ed.getPath();
|
||||
if (path.equals(p)) {
|
||||
return true;
|
||||
}
|
||||
if (path.endsWith("[x]")) { // it should
|
||||
path = path.substring(0, path.length()-3);
|
||||
if (p.startsWith(path) && p.length() > path.length() && !p.substring(path.length()).contains(".")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean typeMatches(ElementDefinition ed, String typeCode) {
|
||||
return ed.getType().size() == 1 && typeCode.equals(ed.getTypeFirstRep().getWorkingCode());
|
||||
}
|
||||
|
||||
private void checkTypeParameters(StructureDefinition base, StructureDefinition derived) {
|
||||
String bt = ToolingExtensions.readStringExtension(base, ToolingExtensions.EXT_TYPE_PARAMETER);
|
||||
if (!derived.hasExtension(ToolingExtensions.EXT_TYPE_PARAMETER)) {
|
||||
|
@ -2409,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()) {
|
||||
|
@ -2441,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()));
|
||||
}
|
||||
|
|
|
@ -237,7 +237,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
private Object lock = new Object(); // used as a lock for the data that follows
|
||||
protected String version; // although the internal resources are all R5, the version of FHIR they describe may not be
|
||||
|
||||
protected final TerminologyClientManager terminologyClientManager = new TerminologyClientManager(new TerminologyClientR5.TerminologyClientR5Factory(), UUID.randomUUID().toString());
|
||||
private boolean minimalMemory = false;
|
||||
|
||||
private Map<String, Map<String, ResourceProxy>> allResourcesById = new HashMap<String, Map<String, ResourceProxy>>();
|
||||
|
@ -279,6 +278,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
protected boolean noTerminologyServer;
|
||||
private int expandCodesLimit = 1000;
|
||||
protected org.hl7.fhir.r5.context.ILoggingService logger = new SystemOutLoggingService();
|
||||
protected final TerminologyClientManager terminologyClientManager = new TerminologyClientManager(new TerminologyClientR5.TerminologyClientR5Factory(), UUID.randomUUID().toString(), logger);
|
||||
protected Parameters expParameters;
|
||||
private Map<String, PackageInformation> packages = new HashMap<>();
|
||||
|
||||
|
@ -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;
|
||||
//}
|
||||
}
|
||||
|
@ -2031,6 +2051,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
|
||||
public void setLogger(@Nonnull org.hl7.fhir.r5.context.ILoggingService logger) {
|
||||
this.logger = logger;
|
||||
getTxClientManager().setLogger(logger);
|
||||
}
|
||||
|
||||
public Parameters getExpansionParameters() {
|
||||
|
|
|
@ -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("");
|
||||
|
|
|
@ -476,7 +476,7 @@ public class Element extends Base implements NamedItem {
|
|||
} else {
|
||||
Element ne = new Element(child).setFormat(format);
|
||||
children.add(ne);
|
||||
numberChildren();
|
||||
ne.index = children.getSizeByName(ne.getListName()) - 1;
|
||||
childForValue = ne;
|
||||
break;
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ public class Element extends Base implements NamedItem {
|
|||
} else {
|
||||
Element ne = new Element(child).setFormat(format);
|
||||
children.add(ne);
|
||||
numberChildren();
|
||||
ne.index = children.getSizeByName(ne.getListName()) - 1;
|
||||
return ne;
|
||||
}
|
||||
}
|
||||
|
@ -574,6 +574,7 @@ public class Element extends Base implements NamedItem {
|
|||
if (p.getName().equals(name)) {
|
||||
Element ne = new Element(name, p).setFormat(format);
|
||||
children.add(ne);
|
||||
ne.index = children.getSizeByName(ne.getListName()) - 1;
|
||||
return ne;
|
||||
} else if (p.getDefinition().isChoice() && name.startsWith(p.getName().replace("[x]", ""))) {
|
||||
String type = name.substring(p.getName().length()-3);
|
||||
|
@ -583,6 +584,7 @@ public class Element extends Base implements NamedItem {
|
|||
Element ne = new Element(name, p).setFormat(format);
|
||||
ne.setType(type);
|
||||
children.add(ne);
|
||||
ne.index = children.getSizeByName(ne.getListName()) - 1;
|
||||
return ne;
|
||||
|
||||
}
|
||||
|
@ -606,6 +608,7 @@ public class Element extends Base implements NamedItem {
|
|||
if (p.getName().equals(name)) {
|
||||
Element ne = new Element(name, p).setFormat(format);
|
||||
children.add(ne);
|
||||
ne.index = children.getSizeByName(ne.getListName()) - 1;
|
||||
return ne;
|
||||
}
|
||||
}
|
||||
|
@ -1664,4 +1667,4 @@ public class Element extends Base implements NamedItem {
|
|||
return this.elided;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ 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.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
||||
|
@ -144,7 +145,11 @@ public class Manager {
|
|||
}
|
||||
|
||||
public static Element build(IWorkerContext context, StructureDefinition sd) {
|
||||
Property p = new Property(context, sd.getSnapshot().getElementFirstRep(), sd);
|
||||
return build(context, sd, new ProfileUtilities(context, null, null));
|
||||
}
|
||||
|
||||
public static Element build(IWorkerContext context, StructureDefinition sd, ProfileUtilities profileUtilities) {
|
||||
Property p = new Property(context, sd.getSnapshot().getElementFirstRep(), sd, profileUtilities, new ContextUtilities(context));
|
||||
Element e = new Element(p.getName(), p);
|
||||
e.setPath(sd.getType());
|
||||
return e;
|
||||
|
|
|
@ -189,6 +189,13 @@ public class FHIRPathEngine {
|
|||
// the application can implement them by providing a constant resolver
|
||||
public interface IEvaluationContext {
|
||||
|
||||
public abstract class FunctionDefinition {
|
||||
public abstract String name();
|
||||
public abstract FunctionDetails details();
|
||||
public abstract TypeDetails check(FHIRPathEngine engine, Object appContext, TypeDetails focus, List<TypeDetails> parameters);
|
||||
public abstract List<Base> execute(FHIRPathEngine engine, Object appContext, List<Base> focus, List<List<Base>> parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant reference - e.g. a reference to a name that must be resolved in context.
|
||||
* The % will be removed from the constant name before this is invoked.
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package org.hl7.fhir.r5.liquid;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package org.hl7.fhir.r5.liquid;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPrimitive() {
|
||||
return j.isJsonPrimitive();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String primitiveValue() {
|
||||
return toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package org.hl7.fhir.r5.liquid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext.FunctionDefinition;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
|
||||
import org.hl7.fhir.r5.fhirpath.TypeDetails;
|
||||
import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.DateTimeType;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
import com.microsoft.schemas.office.visio.x2012.main.impl.FunctionDefTypeImpl;
|
||||
|
||||
public class GlobalObject extends Base {
|
||||
|
||||
private DateTimeType dt;
|
||||
private StringType pathToSpec;
|
||||
|
||||
public GlobalObject(DateTimeType td, StringType pathToSpec) {
|
||||
super();
|
||||
this.dt = td;
|
||||
this.pathToSpec = pathToSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "GlobalObject";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
throw new Error("Read only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirPublication getFHIRPublicationVersion() {
|
||||
return FhirPublication.R5;
|
||||
}
|
||||
|
||||
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
|
||||
if ("dateTime".equals(name)) {
|
||||
return wrap(dt);
|
||||
} else if ("path".equals(name)) {
|
||||
return wrap(pathToSpec);
|
||||
} else {
|
||||
return super.getProperty(hash, name, checkValid);
|
||||
}
|
||||
}
|
||||
|
||||
private Base[] wrap(Base b) {
|
||||
Base[] l = new Base[1];
|
||||
l[0] = b;
|
||||
return l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class GlobalObjectRandomFunction extends FunctionDefinition {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "random";
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionDetails details() {
|
||||
return new FunctionDetails("Generate a Random Number", 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeDetails check(FHIRPathEngine engine, Object appContext, TypeDetails focus, List<TypeDetails> parameters) {
|
||||
if (focus.hasType("GlobalObject")) {
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, "integer");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Base> execute(FHIRPathEngine engine, Object appContext, List<Base> focus, List<List<Base>> parameters) {
|
||||
List<Base> list = new ArrayList<>();
|
||||
int scale = Utilities.parseInt(parameters.get(0).get(0).primitiveValue(), 100)+ 1;
|
||||
list.add(new IntegerType((int)(Math.random() * scale)));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
package org.hl7.fhir.r5.liquid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -42,13 +42,19 @@ import org.hl7.fhir.r5.context.IWorkerContext;
|
|||
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRLexer;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.fhirpath.TypeDetails;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.ExpressionNodeWithOffset;
|
||||
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.BooleanType;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
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.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
|
@ -56,6 +62,94 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
|||
|
||||
public class LiquidEngine implements IEvaluationContext {
|
||||
|
||||
public static class LiquidForLoopObject extends Base {
|
||||
|
||||
private static final long serialVersionUID = 6951452522873320076L;
|
||||
private boolean first;
|
||||
private int index;
|
||||
private int index0;
|
||||
private int rindex;
|
||||
private int rindex0;
|
||||
private boolean last;
|
||||
private int length;
|
||||
private LiquidForLoopObject parentLoop;
|
||||
|
||||
|
||||
public LiquidForLoopObject(int size, int i, int offset, int limit, LiquidForLoopObject parentLoop) {
|
||||
super();
|
||||
this.parentLoop = parentLoop;
|
||||
if (offset == -1) {
|
||||
offset = 0;
|
||||
}
|
||||
if (limit == -1) {
|
||||
limit = size;
|
||||
}
|
||||
|
||||
first = i == offset;
|
||||
index = i+1-offset;
|
||||
index0 = i-offset;
|
||||
rindex = (limit-offset) - 1 - i;
|
||||
rindex0 = (limit-offset) - i;
|
||||
length = limit-offset;
|
||||
last = i == (limit-offset)-1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
throw new Error("forLoop is read only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("forLoop is read only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirPublication getFHIRPublicationVersion() {
|
||||
return FhirPublication.R5;
|
||||
}
|
||||
|
||||
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
|
||||
switch (name) {
|
||||
case "parentLoop" : return wrap(parentLoop);
|
||||
case "first" : return wrap(new BooleanType(first));
|
||||
case "last" : return wrap(new BooleanType(last));
|
||||
case "index" : return wrap(new IntegerType(index));
|
||||
case "index0" : return wrap(new IntegerType(index0));
|
||||
case "rindex" : return wrap(new IntegerType(rindex));
|
||||
case "rindex0" : return wrap(new IntegerType(rindex0));
|
||||
case "length" : return wrap(new IntegerType(length));
|
||||
}
|
||||
|
||||
return super.getProperty(hash, name, checkValid);
|
||||
}
|
||||
|
||||
private Base[] wrap(Base b) {
|
||||
Base[] l = new Base[1];
|
||||
l[0] = b;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "forLoop";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "ForLoop";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface ILiquidRenderingSupport {
|
||||
String renderForLiquid(Object appContext, Base i) throws FHIRException;
|
||||
}
|
||||
|
@ -68,16 +162,19 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
private FHIRPathEngine engine;
|
||||
private ILiquidEngineIncludeResolver includeResolver;
|
||||
private ILiquidRenderingSupport renderingSupport;
|
||||
|
||||
private MarkDownProcessor processor = new MarkDownProcessor(Dialect.COMMON_MARK);
|
||||
private Map<String, Base> vars = new HashMap<>();
|
||||
|
||||
private class LiquidEngineContext {
|
||||
private Object externalContext;
|
||||
private Map<String, Base> loopVars = new HashMap<>();
|
||||
private Map<String, Base> globalVars = new HashMap<>();
|
||||
|
||||
public LiquidEngineContext(Object externalContext) {
|
||||
public LiquidEngineContext(Object externalContext, Map<String, Base> vars) {
|
||||
super();
|
||||
this.externalContext = externalContext;
|
||||
globalVars = new HashMap<>();
|
||||
globalVars.putAll(vars);
|
||||
}
|
||||
|
||||
public LiquidEngineContext(Object externalContext, LiquidEngineContext existing) {
|
||||
|
@ -119,13 +216,17 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
this.renderingSupport = renderingSupport;
|
||||
}
|
||||
|
||||
public Map<String, Base> getVars() {
|
||||
return vars;
|
||||
}
|
||||
|
||||
public LiquidDocument parse(String source, String sourceName) throws FHIRException {
|
||||
return new LiquidParser(source).parse(sourceName);
|
||||
}
|
||||
|
||||
public String evaluate(LiquidDocument document, Base resource, Object appContext) throws FHIRException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
LiquidEngineContext ctxt = new LiquidEngineContext(appContext);
|
||||
LiquidEngineContext ctxt = new LiquidEngineContext(appContext, vars );
|
||||
for (LiquidNode n : document.body) {
|
||||
n.evaluate(b, resource, ctxt);
|
||||
}
|
||||
|
@ -162,12 +263,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 +334,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;
|
||||
|
@ -375,6 +501,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
Collections.reverse(list);
|
||||
}
|
||||
int i = 0;
|
||||
LiquidForLoopObject parentLoop = (LiquidForLoopObject) lctxt.globalVars.get("forLoop");
|
||||
for (Base o : list) {
|
||||
if (offset >= 0 && i < offset) {
|
||||
i++;
|
||||
|
@ -383,6 +510,8 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
if (limit >= 0 && i == limit) {
|
||||
break;
|
||||
}
|
||||
LiquidForLoopObject forloop = new LiquidForLoopObject(list.size(), i, offset, limit, parentLoop);
|
||||
lctxt.globalVars.put("forLoop", forloop);
|
||||
if (lctxt.globalVars.containsKey(varName)) {
|
||||
throw new FHIRException(engine.getWorker().formatMessage(I18nConstants.LIQUID_VARIABLE_ALREADY_ASSIGNED, varName));
|
||||
}
|
||||
|
@ -403,6 +532,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
i++;
|
||||
}
|
||||
lctxt.globalVars.put("forLoop", parentLoop);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +579,20 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
}
|
||||
|
||||
private class LiquidCapture extends LiquidNode {
|
||||
private String varName;
|
||||
private List<LiquidNode> body = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
StringBuilder bc = new StringBuilder();
|
||||
for (LiquidNode n : body) {
|
||||
n.evaluate(bc, resource, ctxt);
|
||||
}
|
||||
ctxt.globalVars.put(varName, new StringType(bc.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidInclude extends LiquidNode {
|
||||
private String page;
|
||||
private Map<String, ExpressionNode> params = new HashMap<>();
|
||||
|
@ -489,6 +633,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;
|
||||
}
|
||||
|
||||
|
@ -569,6 +716,8 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
list.add(parseInclude(cnt.substring(7).trim()));
|
||||
else if (cnt.startsWith("assign "))
|
||||
list.add(parseAssign(cnt.substring(6).trim()));
|
||||
else if (cnt.startsWith("capture "))
|
||||
list.add(parseCapture(cnt.substring(7).trim()));
|
||||
else
|
||||
throw new FHIRException(engine.getWorker().formatMessage(I18nConstants.LIQUID_UNKNOWN_FLOW_STMT,name, cnt));
|
||||
} else { // next2() == '{'
|
||||
|
@ -697,6 +846,16 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
return res;
|
||||
}
|
||||
|
||||
private LiquidNode parseCapture(String cnt) throws FHIRException {
|
||||
int i = 0;
|
||||
while (i < cnt.length() && !Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
LiquidCapture res = new LiquidCapture();
|
||||
res.varName = cnt.substring(0, i);
|
||||
parseList(res.body, true, new String[] { "endcapture" });
|
||||
return res;
|
||||
}
|
||||
|
||||
private LiquidNode parseAssign(String cnt) throws FHIRException {
|
||||
int i = 0;
|
||||
while (!Character.isWhitespace(cnt.charAt(i)))
|
|
@ -36,7 +36,7 @@ import java.util.Map;
|
|||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
@ -629,4 +629,10 @@ public abstract class Base implements Serializable, IBase, IElement {
|
|||
}
|
||||
|
||||
public abstract FhirPublication getFHIRPublicationVersion();
|
||||
|
||||
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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())) {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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+";");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.ILiquidRenderingSupport;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.LiquidDocument;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.ILiquidRenderingSupport;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ public class ResourceWrapperModel extends ResourceWrapper {
|
|||
}
|
||||
|
||||
public String getWebPath() {
|
||||
return null;
|
||||
return model.getWebPath();
|
||||
}
|
||||
|
||||
public String getCodeSystemUri() {
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Set;
|
|||
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager;
|
||||
import org.hl7.fhir.r5.context.ILoggingService;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
|
@ -27,6 +28,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.TerminologyClientContextUseType;
|
||||
import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ServerOptionList;
|
||||
import org.hl7.fhir.r5.terminologies.client.TerminologyClientR5.TerminologyClientR5Factory;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedCodeSystem;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet;
|
||||
|
@ -86,11 +88,14 @@ public class TerminologyClientManager {
|
|||
}
|
||||
|
||||
public class InternalLogEvent {
|
||||
private boolean error;
|
||||
private String message;
|
||||
private String server;
|
||||
private String vs;
|
||||
private String systems;
|
||||
private String choices;
|
||||
private String context;
|
||||
private String request;
|
||||
protected InternalLogEvent(String message, String server, String vs, String systems, String choices) {
|
||||
super();
|
||||
this.message = message;
|
||||
|
@ -99,9 +104,12 @@ public class TerminologyClientManager {
|
|||
this.systems = systems;
|
||||
this.choices = choices;
|
||||
}
|
||||
protected InternalLogEvent(String message) {
|
||||
protected InternalLogEvent(String message, String ctxt, String request) {
|
||||
super();
|
||||
error = true;
|
||||
this.message = message;
|
||||
this.context = ctxt;
|
||||
this.request = request;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
|
@ -118,7 +126,15 @@ public class TerminologyClientManager {
|
|||
public String getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return error;
|
||||
}
|
||||
public String getContext() {
|
||||
return context;
|
||||
}
|
||||
public String getRequest() {
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String UNRESOLVED_VALUESET = "--unknown--";
|
||||
|
@ -142,10 +158,13 @@ public class TerminologyClientManager {
|
|||
|
||||
private boolean useEcosystem;
|
||||
|
||||
public TerminologyClientManager(ITerminologyClientFactory factory, String cacheId) {
|
||||
private ILoggingService logger;
|
||||
|
||||
public TerminologyClientManager(ITerminologyClientFactory factory, String cacheId, ILoggingService logger) {
|
||||
super();
|
||||
this.factory = factory;
|
||||
this.cacheId = cacheId;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public String getCacheId() {
|
||||
|
@ -301,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());
|
||||
|
@ -346,11 +374,11 @@ public class TerminologyClientManager {
|
|||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
String msg = "Error resolving system "+url+": "+e.getMessage()+" ("+request+")";
|
||||
String msg = "Error resolving system "+url+": "+e.getMessage();
|
||||
if (!hasMessage(msg)) {
|
||||
internalLog.add(new InternalLogEvent(msg));
|
||||
internalLog.add(new InternalLogEvent(msg, url, request));
|
||||
}
|
||||
if (!monitorServiceURL.contains("tx.fhir.org")) {
|
||||
if (logger.isDebugLogging()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -526,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) {
|
||||
}
|
||||
}
|
||||
|
@ -571,12 +599,13 @@ public class TerminologyClientManager {
|
|||
ValueSet vs = (ValueSet) client.getClient().read("ValueSet", rid);
|
||||
return new SourcedValueSet(server, vs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage()+" ("+request+")";
|
||||
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage();
|
||||
if (!hasMessage(msg)) {
|
||||
internalLog.add(new InternalLogEvent(msg));
|
||||
internalLog.add(new InternalLogEvent(msg, canonical, request));
|
||||
}
|
||||
if (logger.isDebugLogging()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -607,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) {
|
||||
}
|
||||
}
|
||||
|
@ -651,12 +680,13 @@ public class TerminologyClientManager {
|
|||
CodeSystem vs = (CodeSystem) client.getClient().read("CodeSystem", rid);
|
||||
return new SourcedCodeSystem(server, vs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage()+" ("+request+")";
|
||||
String msg = "Error resolving CodeSystem "+canonical+": "+e.getMessage();
|
||||
if (!hasMessage(msg)) {
|
||||
internalLog.add(new InternalLogEvent(msg));
|
||||
internalLog.add(new InternalLogEvent(msg, canonical, request));
|
||||
}
|
||||
if (logger.isDebugLogging()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -673,4 +703,14 @@ public class TerminologyClientManager {
|
|||
public List<InternalLogEvent> getInternalLog() {
|
||||
return internalLog;
|
||||
}
|
||||
|
||||
public ILoggingService getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void setLogger(ILoggingService logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
case "$url$": return "\"A URL\"";
|
||||
case "$token$": return "\"A Token\"";
|
||||
case "$version$": return variables.containsKey("version") ? variables.get("version") : "(anything)";
|
||||
case "$semver$": return "A semver";
|
||||
default: return "Unhandled template: "+expected;
|
||||
}
|
||||
}
|
||||
|
@ -558,6 +559,7 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
case "$id$": return actualJsonString.matches("[A-Za-z0-9\\-\\.]{1,64}");
|
||||
case "$url$": return actualJsonString.matches("(https?://|www\\.)[-a-zA-Z0-9+&@#/%?=~_|!:.;]*[-a-zA-Z0-9+&@#/%=~_|]");
|
||||
case "$token$": return actualJsonString.matches("[0-9a-zA-Z_][0-9a-zA-Z_\\.\\-]*");
|
||||
case "$semver$": return actualJsonString.matches("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
|
||||
case "$version$": return matchesVariable(actualJsonString, "version");
|
||||
default:
|
||||
throw new Error("Unhandled template: "+expectedJsonString);
|
||||
|
|
|
@ -441,7 +441,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
|
|||
try {
|
||||
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
|
||||
} catch (Exception e) {
|
||||
handleException(0, "An error has occurred while trying to retrieve history since last update", e);
|
||||
handleException(0, "An error has occurred while trying to read a bundle", e);
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hl7.fhir.r5.utils.client.EFhirClientException;
|
|||
import org.hl7.fhir.r5.utils.client.ResourceFormat;
|
||||
import org.hl7.fhir.utilities.MimeType;
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.http.*;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;
|
||||
|
||||
|
@ -162,7 +163,11 @@ public class FhirRequestBuilder {
|
|||
boolean ok = code >= 200 && code < 300;
|
||||
if (response.getContent() == null) {
|
||||
if (!ok) {
|
||||
throw new EFhirClientException(code, response.getMessage());
|
||||
if (Utilities.noString(response.getMessage())) {
|
||||
throw new EFhirClientException(code, response.getMessagefromCode());
|
||||
} else {
|
||||
throw new EFhirClientException(code, response.getMessage());
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
|
||||
|
@ -10,7 +11,7 @@ public interface ITransformerServices {
|
|||
// public boolean validateByValueSet(Coding code, String valuesetId);
|
||||
public void log(String message); // log internal progress
|
||||
|
||||
public Base createType(Object appInfo, String name) throws FHIRException;
|
||||
public Base createType(Object appInfo, String name, ProfileUtilities profileUtilities) throws FHIRException;
|
||||
|
||||
public Base createResource(Object appInfo, Base res, boolean atRootofTransform); // an already created resource is provided; this is to identify/store it
|
||||
|
||||
|
|
|
@ -1788,7 +1788,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
}
|
||||
}
|
||||
Base res = services != null ? services.createType(context.getAppInfo(), tn) : typeFactory(tn);
|
||||
Base res = services != null ? services.createType(context.getAppInfo(), tn, profileUtilities) : typeFactory(tn);
|
||||
if (res.isResource() && !res.fhirType().equals("Parameters")) {
|
||||
// res.setIdBase(tgt.getParameter().size() > 1 ? getParamString(vars, tgt.getParameter().get(0)) : UUID.randomUUID().toString().toLowerCase());
|
||||
if (services != null)
|
||||
|
@ -1929,7 +1929,7 @@ public class StructureMapUtilities {
|
|||
if (sd == null) {
|
||||
throw new FHIRException("Unable to create type "+tn);
|
||||
} else {
|
||||
return Manager.build(worker, sd);
|
||||
return Manager.build(worker, sd, profileUtilities);
|
||||
}
|
||||
} else {
|
||||
return ResourceFactory.createResourceOrType(tn);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -11,11 +11,11 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||
import org.apache.commons.collections4.map.HashedMap;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.ILiquidEngineIncludeResolver;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.LiquidDocument;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.ILiquidEngineIncludeResolver;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
|
@ -52,6 +53,7 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
StructureMap structureMap = scu.parse(fileMap, "cast");
|
||||
Element target = Manager.build(context, scu.getTargetType(structureMap));
|
||||
scu.transform(null, source, structureMap, target);
|
||||
checkNumberChildren(target, "");
|
||||
FHIRPathEngine fp = new FHIRPathEngine(context);
|
||||
Assertions.assertEquals("implicit",fp.evaluateToString(target, "extension[0].value"));
|
||||
Assertions.assertEquals("explicit",fp.evaluateToString(target, "extension[1].value"));
|
||||
|
@ -67,6 +69,7 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
StructureMap structureMap = scu.parse(fileMap, "qr2patfordates");
|
||||
Element target = Manager.build(context, scu.getTargetType(structureMap));
|
||||
scu.transform(null, source, structureMap, target);
|
||||
checkNumberChildren(target, "");
|
||||
FHIRPathEngine fp = new FHIRPathEngine(context);
|
||||
assertEquals("2023-10-26", fp.evaluateToString(target, "birthDate"));
|
||||
assertEquals("2023-09-20T13:19:13.502Z", fp.evaluateToString(target, "deceased"));
|
||||
|
@ -81,6 +84,7 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
StructureMap structureMap = scu.parse(fileMap, "whereclause");
|
||||
Element target = Manager.build(context, scu.getTargetType(structureMap));
|
||||
scu.transform(null, source, structureMap, target);
|
||||
checkNumberChildren(target, "");
|
||||
FHIRPathEngine fp = new FHIRPathEngine(context);
|
||||
assertEquals("true", fp.evaluateToString(target, "rest.resource.interaction.where(code='create').exists()"));
|
||||
}
|
||||
|
@ -134,13 +138,37 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
Assertions.assertEquals("-quote", structureMap.getGroup().get(0).getRule().get(1).getSourceFirstRep().getElement());
|
||||
Assertions.assertEquals("-backtick", structureMap.getGroup().get(0).getRule().get(2).getSourceFirstRep().getElement());
|
||||
}
|
||||
|
||||
// assert indices are equal to Element.numberChildren()
|
||||
private void checkNumberChildren(Element e, String indent) {
|
||||
System.out.println(indent + e + ", index: " + e.getIndex());
|
||||
String last = "";
|
||||
int index = 0;
|
||||
for (Element child : e.getChildren()) {
|
||||
if (child.getProperty().isList()) {
|
||||
if (last.equals(child.getName())) {
|
||||
index++;
|
||||
} else {
|
||||
last = child.getName();
|
||||
index = 0;
|
||||
}
|
||||
// child.index = index;
|
||||
Assertions.assertEquals(index, child.getIndex());
|
||||
} else {
|
||||
// child.index = -1;
|
||||
Assertions.assertEquals(-1, child.getIndex());
|
||||
}
|
||||
checkNumberChildren(child, indent + " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base createType(Object appInfo, String name) throws FHIRException {
|
||||
public Base createType(Object appInfo, String name, ProfileUtilities profileUtilities) throws FHIRException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
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.liquid.BaseJsonWrapper;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine;
|
||||
import org.hl7.fhir.r5.liquid.LiquidEngine.LiquidDocument;
|
||||
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.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;
|
||||
}
|
||||
}
|
|
@ -53,12 +53,12 @@ public class NamedItemList<T extends org.hl7.fhir.utilities.NamedItemList.NamedI
|
|||
|
||||
@Override
|
||||
public boolean add(T e) {
|
||||
map = null;
|
||||
addToMap(e);
|
||||
return list.add(e);
|
||||
}
|
||||
public void add(int index, T e) {
|
||||
addToMap(e);
|
||||
list.add(index, e);
|
||||
map = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,7 +74,9 @@ public class NamedItemList<T extends org.hl7.fhir.utilities.NamedItemList.NamedI
|
|||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> c) {
|
||||
map = null;
|
||||
for(T e : c) {
|
||||
addToMap(e);
|
||||
}
|
||||
return list.addAll(c);
|
||||
}
|
||||
|
||||
|
@ -115,6 +117,14 @@ public class NamedItemList<T extends org.hl7.fhir.utilities.NamedItemList.NamedI
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int getSizeByName(String name) {
|
||||
if (map == null) {
|
||||
buildMap();
|
||||
}
|
||||
List<T> l = map.get(name);
|
||||
return l == null ? 0 : l.size();
|
||||
}
|
||||
|
||||
public T get(int c) {
|
||||
return list.get(c);
|
||||
|
@ -123,15 +133,23 @@ public class NamedItemList<T extends org.hl7.fhir.utilities.NamedItemList.NamedI
|
|||
private void buildMap() {
|
||||
map = new HashMap<>();
|
||||
for (T child : list) {
|
||||
String n = child.getListName();
|
||||
List<T> l = map.get(n);
|
||||
if (l == null) {
|
||||
l = new ArrayList<>();
|
||||
map.put(n,l);
|
||||
}
|
||||
l.add(child);
|
||||
addToMap(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToMap(T child) {
|
||||
if (map == null) {
|
||||
// map will be re-built anyway in next call to getByName
|
||||
return;
|
||||
}
|
||||
String n = child.getListName();
|
||||
List<T> l = map.get(n);
|
||||
if (l == null) {
|
||||
l = new ArrayList<>();
|
||||
map.put(n,l);
|
||||
}
|
||||
l.add(child);
|
||||
}
|
||||
|
||||
public void sort(Comparator<? super T> sorter) {
|
||||
Collections.sort(list, sorter);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,4 +56,74 @@ public class HTTPResult {
|
|||
public String getContentAsString() {
|
||||
return new String(content, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
public String getMessagefromCode() {
|
||||
switch (getCode()) {
|
||||
case 100: return ""+getCode()+" Continue";
|
||||
case 101: return ""+getCode()+" Switching Protocols";
|
||||
case 102: return ""+getCode()+" Processing Deprecated";
|
||||
case 103: return ""+getCode()+" Early Hints";
|
||||
case 200: return ""+getCode()+" OK";
|
||||
case 201: return ""+getCode()+" Created";
|
||||
case 202: return ""+getCode()+" Accepted";
|
||||
case 203: return ""+getCode()+" Non-Authoritative Information";
|
||||
case 204: return ""+getCode()+" No Content";
|
||||
case 205: return ""+getCode()+" Reset Content";
|
||||
case 206: return ""+getCode()+" Partial Content";
|
||||
case 207: return ""+getCode()+" Multi-Status";
|
||||
case 208: return ""+getCode()+" Already Reported";
|
||||
case 226: return ""+getCode()+" IM Used";
|
||||
case 300: return ""+getCode()+" Multiple Choices";
|
||||
case 301: return ""+getCode()+" Moved Permanently";
|
||||
case 302: return ""+getCode()+" Found";
|
||||
case 303: return ""+getCode()+" See Other";
|
||||
case 304: return ""+getCode()+" Not Modified";
|
||||
case 305: return ""+getCode()+" Use Proxy Deprecated";
|
||||
case 306: return ""+getCode()+" unused";
|
||||
case 307: return ""+getCode()+" Temporary Redirect";
|
||||
case 308: return ""+getCode()+" Permanent Redirect";
|
||||
case 400: return ""+getCode()+" Bad Request";
|
||||
case 401: return ""+getCode()+" Unauthorized";
|
||||
case 402: return ""+getCode()+" Payment Required";
|
||||
case 403: return ""+getCode()+" Forbidden";
|
||||
case 404: return ""+getCode()+" Not Found";
|
||||
case 405: return ""+getCode()+" Method Not Allowed";
|
||||
case 406: return ""+getCode()+" Not Acceptable";
|
||||
case 407: return ""+getCode()+" Proxy Authentication Required";
|
||||
case 408: return ""+getCode()+" Request Timeout";
|
||||
case 409: return ""+getCode()+" Conflict";
|
||||
case 410: return ""+getCode()+" Gone";
|
||||
case 411: return ""+getCode()+" Length Required";
|
||||
case 412: return ""+getCode()+" Precondition Failed";
|
||||
case 413: return ""+getCode()+" Content Too Large";
|
||||
case 414: return ""+getCode()+" URI Too Long";
|
||||
case 415: return ""+getCode()+" Unsupported Media Type";
|
||||
case 416: return ""+getCode()+" Range Not Satisfiable";
|
||||
case 417: return ""+getCode()+" Expectation Failed";
|
||||
case 418: return ""+getCode()+" I'm a teapot";
|
||||
case 421: return ""+getCode()+" Misdirected Request";
|
||||
case 422: return ""+getCode()+" Unprocessable Content";
|
||||
case 423: return ""+getCode()+" Locked";
|
||||
case 424: return ""+getCode()+" Failed Dependency";
|
||||
case 425: return ""+getCode()+" Too Early Experimental";
|
||||
case 426: return ""+getCode()+" Upgrade Required";
|
||||
case 428: return ""+getCode()+" Precondition Required";
|
||||
case 429: return ""+getCode()+" Too Many Requests";
|
||||
case 431: return ""+getCode()+" Request Header Fields Too Large";
|
||||
case 451: return ""+getCode()+" Unavailable For Legal Reasons";
|
||||
case 500: return ""+getCode()+" Internal Server Error";
|
||||
case 501: return ""+getCode()+" Not Implemented";
|
||||
case 502: return ""+getCode()+" Bad Gateway";
|
||||
case 503: return ""+getCode()+" Service Unavailable";
|
||||
case 504: return ""+getCode()+" Gateway Timeout";
|
||||
case 505: return ""+getCode()+" HTTP Version Not Supported";
|
||||
case 506: return ""+getCode()+" Variant Also Negotiates";
|
||||
case 507: return ""+getCode()+" Insufficient Storage";
|
||||
case 508: return ""+getCode()+" Loop Detected";
|
||||
case 510: return ""+getCode()+" Not Extended";
|
||||
case 511: return ""+getCode()+" Network Authentication Required";
|
||||
default: return "HTTP code "+code;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,6 @@ public class CommonPackages {
|
|||
public static final String VER_XVER = "0.1.0";
|
||||
|
||||
public static final String ID_PUBPACK = "hl7.fhir.pubpack";
|
||||
public static final String VER_PUBPACK = "0.1.9";
|
||||
public static final String VER_PUBPACK = "0.2.0";
|
||||
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ public class FilesystemPackageCacheManagerLocks {
|
|||
channel.close();
|
||||
throw new IOException("Lock file exists, but is not locked by a process: " + lockFile.getName());
|
||||
}
|
||||
System.out.println("File is locked.");
|
||||
System.out.println("File is locked ('"+lockFile.getAbsolutePath()+"').");
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -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) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@ import java.io.PrintWriter;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
@ -34,9 +35,9 @@ public class TransformSupportServices implements ITransformerServices {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Base createType(Object appInfo, String name) throws FHIRException {
|
||||
public Base createType(Object appInfo, String name, ProfileUtilities profileUtilities) throws FHIRException {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, name);
|
||||
return Manager.build(context, sd);
|
||||
return Manager.build(context, sd, profileUtilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2478,22 +2478,26 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
if (ctxt.getType() == ExtensionContextType.ELEMENT) {
|
||||
String en = ctxt.getExpression();
|
||||
contexts.append("e:" + en);
|
||||
String pu = null;
|
||||
if (en.contains("#")) {
|
||||
pu = en.substring(0, en.indexOf("#"));
|
||||
en = en.substring(en.indexOf("#")+1);
|
||||
if (en == null) {
|
||||
// nothing? It's an error in the extension definition, but that's properly reported elsewhere
|
||||
} else {
|
||||
//pu = en;
|
||||
}
|
||||
if (Utilities.existsInList(en, "Element", "Any")) {
|
||||
ok = true;
|
||||
} else if (en.equals("Resource") && container.isResource()) {
|
||||
ok = true;
|
||||
} else if (en.equals("CanonicalResource") && containsAny(VersionUtilities.getExtendedCanonicalResourceNames(context.getVersion()), plist)) {
|
||||
ok = true;
|
||||
} else if (hasElementName(plist, en) && pu == null) {
|
||||
ok = true;
|
||||
contexts.append("e:" + en);
|
||||
if (en.contains("#")) {
|
||||
pu = en.substring(0, en.indexOf("#"));
|
||||
en = en.substring(en.indexOf("#")+1);
|
||||
} else {
|
||||
//pu = en;
|
||||
}
|
||||
if (Utilities.existsInList(en, "Element", "Any")) {
|
||||
ok = true;
|
||||
} else if (en.equals("Resource") && container.isResource()) {
|
||||
ok = true;
|
||||
} else if (en.equals("CanonicalResource") && containsAny(VersionUtilities.getExtendedCanonicalResourceNames(context.getVersion()), plist)) {
|
||||
ok = true;
|
||||
} else if (hasElementName(plist, en) && pu == null) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
|
@ -4316,7 +4320,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
Collections.sort(list, new StructureDefinitionSorterByUrl());
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (StructureDefinition sd : list) {
|
||||
b.append(sd.getUrl());
|
||||
b.append(sd.getVersionedUrl());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
|
|
@ -476,14 +476,14 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
qok = warning(errors, NO_RULE_DATE, IssueType.REQUIRED, q.line(), q.col(), stack.getLiteralPath(), qsrc != null, I18nConstants.QUESTIONNAIRE_QR_Q_NOTFOUND, questionnaire);
|
||||
}
|
||||
if (qok) {
|
||||
boolean inProgress = "in-progress".equals(element.getNamedChildValue("status", false));
|
||||
ok = validateQuestionannaireResponseItems(hostContext, qsrc, qsrc.q().getItem(), errors, element, stack, inProgress, element, new QStack(qsrc, element)) && ok;
|
||||
boolean notCompleted = !Utilities.existsInList(element.getNamedChildValue("status", false), "completed", "amended");
|
||||
ok = validateQuestionannaireResponseItems(hostContext, qsrc, qsrc.q().getItem(), errors, element, stack, notCompleted, element, new QStack(qsrc, element)) && ok;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateQuestionnaireResponseItem(ValidationContext hostContext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
|
||||
private boolean validateQuestionnaireResponseItem(ValidationContext hostContext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, Element element, NodeStack stack, boolean notCompleted, Element questionnaireResponseRoot, QStack qstack) {
|
||||
BooleanHolder ok = new BooleanHolder();
|
||||
|
||||
String text = element.getNamedChildValue("text", false);
|
||||
|
@ -491,7 +491,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
|
||||
List<Element> answers = new ArrayList<Element>();
|
||||
element.getNamedChildren("answer", answers);
|
||||
if (inProgress)
|
||||
if (notCompleted)
|
||||
warning(errors, NO_RULE_DATE, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId());
|
||||
else if (myEnableWhenEvaluator.isQuestionEnabled(hostContext, qItem, qstack, fpe)) {
|
||||
ok.see(rule(errors, NO_RULE_DATE, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId()));
|
||||
|
@ -586,7 +586,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
}
|
||||
if (qItem.getType() != QuestionnaireItemType.GROUP) {
|
||||
// if it's a group, we already have an error before getting here, so no need to hammer away on that
|
||||
ok.see(validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, answer, stack, inProgress, questionnaireResponseRoot, qstack));
|
||||
ok.see(validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, answer, stack, notCompleted, questionnaireResponseRoot, qstack));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -601,7 +601,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
element.getNamedChildren("item", items);
|
||||
ok.see(rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), items.isEmpty(), I18nConstants.QUESTIONNAIRE_QR_ITEM_GROUP_ANSWER, qItem.getLinkId()));
|
||||
} else {
|
||||
ok.see(validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, element, stack, inProgress, questionnaireResponseRoot, qstack));
|
||||
ok.see(validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, element, stack, notCompleted, questionnaireResponseRoot, qstack));
|
||||
}
|
||||
return ok.ok();
|
||||
}
|
||||
|
@ -610,14 +610,14 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
return !answers.isEmpty() || !qItem.getRequired() || qItem.getType() == QuestionnaireItemType.GROUP;
|
||||
}
|
||||
|
||||
private boolean validateQuestionnaireResponseItem(ValidationContext hostcontext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, List<ElementWithIndex> elements, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
|
||||
private boolean validateQuestionnaireResponseItem(ValidationContext hostcontext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, List<ElementWithIndex> elements, NodeStack stack, boolean notCompleted, Element questionnaireResponseRoot, QStack qstack) {
|
||||
boolean ok = true;
|
||||
if (elements.size() > 1) {
|
||||
ok = rulePlural(errors, NO_RULE_DATE, IssueType.INVALID, elements.get(1).getElement().line(), elements.get(1).getElement().col(), stack.getLiteralPath(), qItem.getRepeats(), elements.size(), I18nConstants.QUESTIONNAIRE_QR_ITEM_ONLYONEI, qItem.getLinkId()) && ok;
|
||||
}
|
||||
for (ElementWithIndex element : elements) {
|
||||
NodeStack ns = stack.push(element.getElement(), element.getIndex(), null, null);
|
||||
ok = validateQuestionnaireResponseItem(hostcontext, qsrc, qItem, errors, element.getElement(), ns, inProgress, questionnaireResponseRoot, qstack.push(qItem, element.getElement())) && ok;
|
||||
ok = validateQuestionnaireResponseItem(hostcontext, qsrc, qItem, errors, element.getElement(), ns, notCompleted, questionnaireResponseRoot, qstack.push(qItem, element.getElement())) && ok;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
return -1;
|
||||
}
|
||||
|
||||
private boolean validateQuestionannaireResponseItems(ValidationContext hostContext, QuestionnaireWithContext qsrc, List<QuestionnaireItemComponent> qItems, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
|
||||
private boolean validateQuestionannaireResponseItems(ValidationContext hostContext, QuestionnaireWithContext qsrc, List<QuestionnaireItemComponent> qItems, List<ValidationMessage> errors, Element element, NodeStack stack, boolean notCompleted, Element questionnaireResponseRoot, QStack qstack) {
|
||||
boolean ok = true;
|
||||
List<Element> items = new ArrayList<Element>();
|
||||
element.getNamedChildren("item", items);
|
||||
|
@ -647,7 +647,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
if (qItem != null) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, item.line(), item.col(), stack.getLiteralPath(), index > -1, misplacedItemError(qItem)) && ok;
|
||||
NodeStack ns = stack.push(item, counter, null, null);
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, qItem, errors, item, ns, inProgress, questionnaireResponseRoot, qstack.push(qItem, item)) && ok;
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, qItem, errors, item, ns, notCompleted, questionnaireResponseRoot, qstack.push(qItem, item)) && ok;
|
||||
} else
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.NOTFOUND, item.line(), item.col(), stack.getLiteralPath(), index > -1, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOTFOUND, linkId) && ok;
|
||||
} else {
|
||||
|
@ -670,12 +670,12 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
// ok, now we have a list of known items, grouped by linkId. We've made an error for anything out of order
|
||||
for (QuestionnaireItemComponent qItem : qItems) {
|
||||
List<ElementWithIndex> mapItem = map.get(qItem.getLinkId());
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, errors, element, stack, inProgress, questionnaireResponseRoot, qItem, mapItem, qstack) && ok;
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, errors, element, stack, notCompleted, questionnaireResponseRoot, qItem, mapItem, qstack) && ok;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
public boolean validateQuestionnaireResponseItem(ValidationContext hostContext, QuestionnaireWithContext qsrc, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QuestionnaireItemComponent qItem, List<ElementWithIndex> mapItem, QStack qstack) {
|
||||
public boolean validateQuestionnaireResponseItem(ValidationContext hostContext, QuestionnaireWithContext qsrc, List<ValidationMessage> errors, Element element, NodeStack stack, boolean notCompleted, Element questionnaireResponseRoot, QuestionnaireItemComponent qItem, List<ElementWithIndex> mapItem, QStack qstack) {
|
||||
boolean ok = true;
|
||||
boolean enabled = myEnableWhenEvaluator.isQuestionEnabled(hostContext, qItem, qstack, fpe);
|
||||
if (mapItem != null) {
|
||||
|
@ -687,14 +687,14 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
}
|
||||
|
||||
// Recursively validate child items
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, qItem, errors, mapItem, stack, inProgress, questionnaireResponseRoot, qstack) && ok;
|
||||
ok = validateQuestionnaireResponseItem(hostContext, qsrc, qItem, errors, mapItem, stack, notCompleted, questionnaireResponseRoot, qstack) && ok;
|
||||
|
||||
} else {
|
||||
|
||||
// item is missing, is the question enabled?
|
||||
if (enabled && qItem.getRequired()) {
|
||||
String message = context.formatMessage(I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId());
|
||||
if (inProgress) {
|
||||
if (notCompleted) {
|
||||
warning(errors, NO_RULE_DATE, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, message);
|
||||
} else {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, message) && ok;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,14 +568,24 @@ 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();
|
||||
t2.setText(null);
|
||||
t1.setIdBase(t2.getIdBase());
|
||||
Assertions.assertTrue(t1.equalsDeep(t2), "Output does not match expected");
|
||||
}
|
||||
}
|
||||
|
@ -571,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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
2
pom.xml
2
pom.xml
|
@ -23,7 +23,7 @@
|
|||
<commons_io_version>2.17.0</commons_io_version>
|
||||
<guava_version>32.0.1-jre</guava_version>
|
||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||
<validator_test_case_version>1.6.8</validator_test_case_version>
|
||||
<validator_test_case_version>1.6.9-SNAPSHOT</validator_test_case_version>
|
||||
<jackson_version>2.17.0</jackson_version>
|
||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
|
|
Loading…
Reference in New Issue