R4B and R5 extension changes
This commit is contained in:
parent
982ce5f58f
commit
023aea34fb
|
@ -127,12 +127,14 @@ import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
|
|||
import org.hl7.fhir.r5.utils.formats.CSVWriter;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.PackageHacker;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
@ -6846,100 +6848,6 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
public void setMasterSourceFileNames(Set<String> masterSourceFileNames) {
|
||||
this.masterSourceFileNames = masterSourceFileNames;
|
||||
}
|
||||
|
||||
public static int loadR5Extensions(BasePackageCacheManager pcm, IWorkerContext context) throws FHIRException, IOException {
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
String[] types = new String[] { "StructureDefinition", "ValueSet", "CodeSystem" };
|
||||
Map<String, ValueSet> valueSets = new HashMap<>();
|
||||
Map<String, CodeSystem> codeSystems = new HashMap<>();
|
||||
List<StructureDefinition> extensions = new ArrayList<>();
|
||||
JsonParser json = new JsonParser();
|
||||
for (PackageResourceInformation pri : npm.listIndexedResources(types)) {
|
||||
CanonicalResource r = (CanonicalResource) json.parse(npm.load(pri));
|
||||
if (r instanceof CodeSystem) {
|
||||
codeSystems.put(r.getUrl(), (CodeSystem) r);
|
||||
} else if (r instanceof ValueSet) {
|
||||
valueSets.put(r.getUrl(), (ValueSet) r);
|
||||
} else if (r instanceof StructureDefinition) {
|
||||
extensions.add((StructureDefinition) r);
|
||||
}
|
||||
}
|
||||
PackageVersion pd = new PackageVersion(npm.name(), npm.version(), npm.dateAsDate());
|
||||
int c = 0;
|
||||
List<String> typeNames = context.getTypeNames();
|
||||
for (StructureDefinition sd : extensions) {
|
||||
if (sd.getType().equals("Extension") && sd.getDerivation() == TypeDerivationRule.CONSTRAINT &&
|
||||
!context.hasResource(StructureDefinition.class, sd.getUrl())) {
|
||||
if (survivesStrippingTypes(sd, context, typeNames)) {
|
||||
c++;
|
||||
sd.setUserData("path", Utilities.pathURL(npm.getWebLocation(), "extension-"+sd.getId()+".html"));
|
||||
context.cacheResourceFromPackage(sd, pd);
|
||||
registerTerminologies(sd, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void registerTerminologies(StructureDefinition sd, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
|
||||
String vs = ed.getBinding().getValueSet();
|
||||
if (!context.hasResource(StructureDefinition.class, vs)) {
|
||||
loadValueSet(vs, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void loadValueSet(String url, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
if (valueSets.containsKey(url)) {
|
||||
ValueSet vs = valueSets.get(url);
|
||||
context.cacheResourceFromPackage(vs, pd);
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
for (CanonicalType t : inc.getValueSet()) {
|
||||
loadValueSet(t.asStringValue(), context, valueSets, codeSystems, pd);
|
||||
}
|
||||
if (inc.hasSystem()) {
|
||||
if (!context.hasResource(CodeSystem.class, inc.getSystem()) && codeSystems.containsKey(inc.getSystem())) {
|
||||
context.cacheResourceFromPackage(codeSystems.get(inc.getSystem()), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean survivesStrippingTypes(StructureDefinition sd, IWorkerContext context, List<String> typeNames) {
|
||||
for (ElementDefinition ed : sd.getDifferential().getElement()) {
|
||||
stripTypes(ed, context, typeNames);
|
||||
}
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (!stripTypes(ed, context, typeNames)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean stripTypes(ElementDefinition ed, IWorkerContext context, List<String> typeNames) {
|
||||
if (!ed.getPath().contains(".") || !ed.hasType()) {
|
||||
return true;
|
||||
}
|
||||
ed.getType().removeIf(tr -> !typeNames.contains(tr.getWorkingCode()));
|
||||
if (!ed.hasType()) {
|
||||
return false;
|
||||
}
|
||||
for (TypeRefComponent tr : ed.getType()) {
|
||||
if (tr.hasTargetProfile()) {
|
||||
tr.getTargetProfile().removeIf(n -> !context.hasResource(StructureDefinition.class, n.asStringValue()));
|
||||
if (!tr.hasTargetProfile()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package org.hl7.fhir.r5.conformance;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
|
||||
public class R5ExtensionsLoader {
|
||||
private BasePackageCacheManager pcm;
|
||||
private int count;
|
||||
private byte[] map;
|
||||
private NpmPackage pck;
|
||||
|
||||
public R5ExtensionsLoader(BasePackageCacheManager pcm) {
|
||||
super();
|
||||
this.pcm = pcm;
|
||||
}
|
||||
|
||||
public void loadR5Extensions(IWorkerContext context) throws FHIRException, IOException {
|
||||
pck = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
String[] types = new String[] { "StructureDefinition", "ValueSet", "CodeSystem" };
|
||||
Map<String, ValueSet> valueSets = new HashMap<>();
|
||||
Map<String, CodeSystem> codeSystems = new HashMap<>();
|
||||
List<StructureDefinition> extensions = new ArrayList<>();
|
||||
JsonParser json = new JsonParser();
|
||||
for (PackageResourceInformation pri : pck.listIndexedResources(types)) {
|
||||
CanonicalResource r = (CanonicalResource) json.parse(pck.load(pri));
|
||||
if (r instanceof CodeSystem) {
|
||||
codeSystems.put(r.getUrl(), (CodeSystem) r);
|
||||
} else if (r instanceof ValueSet) {
|
||||
valueSets.put(r.getUrl(), (ValueSet) r);
|
||||
} else if (r instanceof StructureDefinition) {
|
||||
extensions.add((StructureDefinition) r);
|
||||
}
|
||||
}
|
||||
PackageVersion pd = new PackageVersion(pck.name(), pck.version(), pck.dateAsDate());
|
||||
count = 0;
|
||||
List<String> typeNames = context.getTypeNames();
|
||||
for (StructureDefinition sd : extensions) {
|
||||
if (sd.getType().equals("Extension") && sd.getDerivation() == TypeDerivationRule.CONSTRAINT &&
|
||||
!context.hasResource(StructureDefinition.class, sd.getUrl())) {
|
||||
if (survivesStrippingTypes(sd, context, typeNames)) {
|
||||
count++;
|
||||
sd.setUserData("path", Utilities.pathURL(pck.getWebLocation(), "extension-"+sd.getId().toLowerCase()+".html"));
|
||||
context.cacheResourceFromPackage(sd, pd);
|
||||
registerTerminologies(sd, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map = pck.hasFile("other", "spec.internals") ? TextFile.streamToBytes(pck.load("other", "spec.internals")) : null;
|
||||
}
|
||||
|
||||
private void registerTerminologies(StructureDefinition sd, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
|
||||
String vs = ed.getBinding().getValueSet();
|
||||
if (!context.hasResource(StructureDefinition.class, vs)) {
|
||||
loadValueSet(vs, context, valueSets, codeSystems, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadValueSet(String url, IWorkerContext context, Map<String, ValueSet> valueSets, Map<String, CodeSystem> codeSystems, PackageVersion pd) {
|
||||
if (valueSets.containsKey(url)) {
|
||||
ValueSet vs = valueSets.get(url);
|
||||
context.cacheResourceFromPackage(vs, pd);
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
for (CanonicalType t : inc.getValueSet()) {
|
||||
loadValueSet(t.asStringValue(), context, valueSets, codeSystems, pd);
|
||||
}
|
||||
if (inc.hasSystem()) {
|
||||
if (!context.hasResource(CodeSystem.class, inc.getSystem()) && codeSystems.containsKey(inc.getSystem())) {
|
||||
context.cacheResourceFromPackage(codeSystems.get(inc.getSystem()), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean survivesStrippingTypes(StructureDefinition sd, IWorkerContext context, List<String> typeNames) {
|
||||
for (ElementDefinition ed : sd.getDifferential().getElement()) {
|
||||
stripTypes(ed, context, typeNames);
|
||||
}
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (!stripTypes(ed, context, typeNames)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean stripTypes(ElementDefinition ed, IWorkerContext context, List<String> typeNames) {
|
||||
if (!ed.getPath().contains(".") || !ed.hasType()) {
|
||||
return true;
|
||||
}
|
||||
ed.getType().removeIf(tr -> !typeNames.contains(tr.getWorkingCode()));
|
||||
if (!ed.hasType()) {
|
||||
return false;
|
||||
}
|
||||
for (TypeRefComponent tr : ed.getType()) {
|
||||
if (tr.hasTargetProfile()) {
|
||||
tr.getTargetProfile().removeIf(n -> !context.hasResource(StructureDefinition.class, n.asStringValue()));
|
||||
if (!tr.hasTargetProfile()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public BasePackageCacheManager getPcm() {
|
||||
return pcm;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public byte[] getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public NpmPackage getPck() {
|
||||
return pck;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -331,7 +331,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) {
|
||||
return;
|
||||
}
|
||||
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url));
|
||||
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url,
|
||||
fetchResourceWithException(r.getType(), url).fhirType()));
|
||||
}
|
||||
switch(r.getType()) {
|
||||
case "StructureDefinition":
|
||||
|
@ -412,7 +413,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) {
|
||||
return;
|
||||
}
|
||||
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url));
|
||||
throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url,
|
||||
fetchResourceWithException(r.getClass(), url).fhirType()));
|
||||
}
|
||||
if (r instanceof StructureDefinition) {
|
||||
StructureDefinition sd = (StructureDefinition) m;
|
||||
|
|
|
@ -416,7 +416,7 @@ No_Parameters_provided_to_expandVS = No Parameters provided to expandVS
|
|||
No_Expansion_Parameters_provided = No Expansion Parameters provided
|
||||
Unable_to_resolve_value_Set_ = Unable to resolve value Set {0}
|
||||
Delimited_versions_have_exact_match_for_delimiter____vs_ = Delimited versions have exact match for delimiter ''{0}'' : {1} vs {2}
|
||||
Duplicate_Resource_ = Duplicate Resource {0}
|
||||
Duplicate_Resource_ = Duplicate Resource {0} of type {1}
|
||||
Error_expanding_ValueSet_running_without_terminology_services = Error expanding ValueSet: running without terminology services
|
||||
Error_validating_code_running_without_terminology_services = Error validating code: running without terminology services
|
||||
Unable_to_validate_code_without_using_server = Unable to validate code without using server
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
|||
import org.hl7.fhir.r5.context.SystemOutLoggingService;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.R5ExtensionsLoader;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
|
@ -341,7 +342,9 @@ public class ValidationService {
|
|||
System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")");
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false);
|
||||
System.out.print(" Load R5 Extensions");
|
||||
System.out.println(" - " + ProfileUtilities.loadR5Extensions(validator.getPcm(), validator.getContext()) + " resources (" + tt.milestone() + ")");
|
||||
R5ExtensionsLoader r5e = new R5ExtensionsLoader(validator.getPcm());
|
||||
r5e.loadR5Extensions(validator.getContext());
|
||||
System.out.println(" - " + r5e.getCount() + " resources (" + tt.milestone() + ")");
|
||||
System.out.print(" Terminology server " + cliContext.getTxServer());
|
||||
String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
|
||||
System.out.println(" - Version " + txver + " (" + tt.milestone() + ")");
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -19,7 +19,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.4.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.102</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.103-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M5</maven_surefire_version>
|
||||
|
|
Loading…
Reference in New Issue