refactor IWorkerContext

This commit is contained in:
Grahame Grieve 2022-10-07 21:50:59 +11:00
parent 9a39f4570c
commit e1657c66b0
37 changed files with 769 additions and 710 deletions

View File

@ -9,6 +9,7 @@ import java.text.SimpleDateFormat;
import java.util.List;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
@ -84,7 +85,7 @@ public class PhinVadsImporter extends OIDBasedValueSetImporter {
String display = rdr.cell("Preferred Concept Name");
String csoid = rdr.cell("Code System OID");
String csver = rdr.cell("Code System Version");
String url = context.oid2Uri(csoid);
String url = new ContextUtilities(context).oid2Uri(csoid);
if (url == null) {
url = "urn:oid:" + csoid;
}

View File

@ -15,6 +15,7 @@ import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.conformance.ProfileUtilities.UnusedTracker;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DataType;
@ -362,7 +363,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
if (val instanceof PrimitiveType)
return "'" + ((PrimitiveType) val).getValueAsString()+"'";
IParser jp = left ? session.getContextLeft().newJsonParser() : session.getContextRight().newJsonParser();
IParser jp = new JsonParser();
return jp.composeString(val, "value");
}

View File

@ -3309,7 +3309,7 @@ public class ProfileUtilities extends TranslatingUtilities {
String url = u.getValue();
boolean tgtOk = !td.hasTargetProfile() || td.hasTargetProfile(url);
while (url != null && !tgtOk) {
StructureDefinition sd = context.fetchRawProfile(url);
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
if (sd == null) {
if (messages != null) {
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, purl+"#"+derived.getPath(), "Cannot check whether the target profile "+url+" is valid constraint on the base because it is not known", IssueSeverity.WARNING));
@ -4396,7 +4396,7 @@ public class ProfileUtilities extends TranslatingUtilities {
Piece p = gc.addText(ProfileUtilities.CONSTRAINT_CHAR);
p.setHint(translate("sd.table", "This element has or is affected by some invariants ("+listConstraintsAndConditions(element)+")"));
p.addStyle(CONSTRAINT_STYLE);
p.setReference(context.getSpecUrl()+"conformance-rules.html#constraints");
p.setReference(VersionUtilities.getSpecUrl(context.getVersion())+"conformance-rules.html#constraints");
}
ExtensionContext extDefn = null;
@ -5321,7 +5321,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (value instanceof PrimitiveType)
return ((PrimitiveType) value).asStringValue();
IParser json = context.newJsonParser();
IParser json = new JsonParser();
return json.composeString(value, null);
}

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Map;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
import org.hl7.fhir.r5.formats.JsonParser;
@ -56,7 +57,7 @@ public class R5ExtensionsLoader {
}
PackageVersion pd = new PackageVersion(pck.name(), pck.version(), pck.dateAsDate());
count = 0;
List<String> typeNames = context.getTypeNames();
List<String> typeNames = new ContextUtilities(context).getTypeNames();
for (StructureDefinition sd : extensions) {
if (sd.getType().equals("Extension") && sd.getDerivation() == TypeDerivationRule.CONSTRAINT &&
!context.hasResource(StructureDefinition.class, sd.getUrl())) {

View File

@ -54,8 +54,8 @@ import org.hl7.fhir.exceptions.NoTerminologyServiceException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
import org.hl7.fhir.r5.context.IWorkerContext.IPackageLoadingTracker;
import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory;
import org.hl7.fhir.r5.context.IWorkerContextManager.IPackageLoadingTracker;
import org.hl7.fhir.r5.context.TerminologyCache.CacheToken;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.Bundle;
@ -70,6 +70,7 @@ import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
@ -246,7 +247,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
protected TerminologyCache txCache;
protected TimeTracker clock;
private boolean tlogging = true;
private ICanonicalResourceLocator locator;
private IWorkerContextManager.ICanonicalResourceLocator locator;
protected String userAgent;
protected BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException {
@ -1297,20 +1298,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
txCache.clear();
}
@Override
public List<ConceptMap> findMapsForSource(String url) throws FHIRException {
synchronized (lock) {
List<ConceptMap> res = new ArrayList<ConceptMap>();
for (ConceptMap map : maps.getList()) {
if (((Reference) map.getSourceScope()).getReference().equals(url)) {
res.add(map);
}
}
return res;
}
}
public boolean isCanRunWithoutTerminology() {
return canRunWithoutTerminology;
}
@ -1383,7 +1370,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
if (class_ == StructureDefinition.class) {
uri = ProfileUtilities.sdNs(uri, getOverrideVersionNs());
uri = ProfileUtilities.sdNs(uri, null);
}
synchronized (lock) {
@ -1509,7 +1496,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
if (uri == null) {
return null;
}
uri = ProfileUtilities.sdNs(uri, getOverrideVersionNs());
uri = ProfileUtilities.sdNs(uri, null);
synchronized (lock) {
@ -1571,7 +1558,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
if ("StructureDefinition".equals(cls)) {
uri = ProfileUtilities.sdNs(uri, getOverrideVersionNs());
uri = ProfileUtilities.sdNs(uri, null);
}
synchronized (lock) {
@ -1693,11 +1680,65 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
throw new FHIRException(formatMessage(I18nConstants.NOT_DONE_YET_CANT_FETCH_, uri));
}
}
@SuppressWarnings("unchecked")
public <T extends Resource> List<T> fetchResourcesByType(Class<T> class_) {
List<T> res = new ArrayList<>();
synchronized (lock) {
if (class_ == Resource.class || class_ == DomainResource.class || class_ == CanonicalResource.class || class_ == null) {
res.addAll((List<T>) structures.getList());
res.addAll((List<T>) guides.getList());
res.addAll((List<T>) capstmts.getList());
res.addAll((List<T>) measures.getList());
res.addAll((List<T>) libraries.getList());
res.addAll((List<T>) valueSets.getList());
res.addAll((List<T>) codeSystems.getList());
res.addAll((List<T>) operations.getList());
res.addAll((List<T>) searchParameters.getList());
res.addAll((List<T>) plans.getList());
res.addAll((List<T>) maps.getList());
res.addAll((List<T>) transforms.getList());
res.addAll((List<T>) questionnaires.getList());
res.addAll((List<T>) systems.getList());
} else if (class_ == ImplementationGuide.class) {
res.addAll((List<T>) guides.getList());
} else if (class_ == CapabilityStatement.class) {
res.addAll((List<T>) capstmts.getList());
} else if (class_ == Measure.class) {
res.addAll((List<T>) measures.getList());
} else if (class_ == Library.class) {
res.addAll((List<T>) libraries.getList());
} else if (class_ == StructureDefinition.class) {
res.addAll((List<T>) structures.getList());
} else if (class_ == StructureMap.class) {
res.addAll((List<T>) transforms.getList());
} else if (class_ == ValueSet.class) {
res.addAll((List<T>) valueSets.getList());
} else if (class_ == CodeSystem.class) {
res.addAll((List<T>) codeSystems.getList());
} else if (class_ == NamingSystem.class) {
res.addAll((List<T>) systems.getList());
} else if (class_ == ConceptMap.class) {
res.addAll((List<T>) maps.getList());
} else if (class_ == PlanDefinition.class) {
res.addAll((List<T>) plans.getList());
} else if (class_ == OperationDefinition.class) {
res.addAll((List<T>) operations.getList());
} else if (class_ == Questionnaire.class) {
res.addAll((List<T>) questionnaires.getList());
} else if (class_ == SearchParameter.class) {
res.addAll((List<T>) searchParameters.getList());
}
}
return res;
}
private Set<String> notCanonical = new HashSet<String>();
private String overrideVersionNs;
protected IPackageLoadingTracker packageTracker;
protected IWorkerContextManager.IPackageLoadingTracker packageTracker;
@Override
public Resource fetchResourceById(String type, String uri) {
@ -1905,25 +1946,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
}
@Override
public List<CanonicalResource> allConformanceResources() {
synchronized (lock) {
List<CanonicalResource> result = new ArrayList<CanonicalResource>();
structures.listAllM(result);
guides.listAllM(result);
capstmts.listAllM(result);
measures.listAllM(result);
libraries.listAllM(result);
codeSystems.listAllM(result);
valueSets.listAllM(result);
maps.listAllM(result);
transforms.listAllM(result);
plans.listAllM(result);
questionnaires.listAllM(result);
systems.listAllM(result);
return result;
}
}
public String listSupportedSystems() {
synchronized (lock) {
@ -1950,20 +1972,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
return m;
}
public List<StructureMap> listTransforms() {
List<StructureMap> m = new ArrayList<StructureMap>();
synchronized (lock) {
transforms.listAll(m);
}
return m;
}
public StructureMap getTransform(String code) {
synchronized (lock) {
return transforms.get(code);
}
}
public List<StructureDefinition> listStructures() {
List<StructureDefinition> m = new ArrayList<StructureDefinition>();
synchronized (lock) {
@ -1978,63 +1986,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
}
@Override
public String oid2Uri(String oid) {
synchronized (lock) {
if (oid != null && oid.startsWith("urn:oid:")) {
oid = oid.substring(8);
}
if (oidCache.containsKey(oid)) {
return oidCache.get(oid);
}
String uri = OIDUtils.getUriForOid(oid);
if (uri != null) {
oidCache.put(oid, uri);
return uri;
}
CodeSystem cs = fetchCodeSystem("http://terminology.hl7.org/CodeSystem/v2-tables");
if (cs != null) {
for (ConceptDefinitionComponent cc : cs.getConcept()) {
for (ConceptPropertyComponent cp : cc.getProperty()) {
if (Utilities.existsInList(cp.getCode(), "v2-table-oid", "v2-cs-oid") && oid.equals(cp.getValue().primitiveValue())) {
for (ConceptPropertyComponent cp2 : cc.getProperty()) {
if ("v2-cs-uri".equals(cp2.getCode())) {
oidCache.put(oid, cp2.getValue().primitiveValue());
return cp2.getValue().primitiveValue();
}
}
}
}
}
}
for (CodeSystem css : codeSystems.getList()) {
if (("urn:oid:"+oid).equals(css.getUrl())) {
oidCache.put(oid, css.getUrl());
return css.getUrl();
}
for (Identifier id : css.getIdentifier()) {
if ("urn:ietf:rfc:3986".equals(id.getSystem()) && ("urn:oid:"+oid).equals(id.getValue())) {
oidCache.put(oid, css.getUrl());
return css.getUrl();
}
}
}
for (NamingSystem ns : systems.getList()) {
if (hasOid(ns, oid)) {
uri = getUri(ns);
if (uri != null) {
oidCache.put(oid, null);
return null;
}
}
}
}
oidCache.put(oid, null);
return null;
}
private String getUri(NamingSystem ns) {
for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) {
if (id.getType() == NamingSystemIdentifierType.URI) {
@ -2065,16 +2016,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
}
@Override
public String getOverrideVersionNs() {
return overrideVersionNs;
}
@Override
public void setOverrideVersionNs(String value) {
overrideVersionNs = value;
}
@Override
public ILoggingService getLogger() {
return logger;
@ -2105,15 +2046,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
this.ucumService = ucumService;
}
@Override
public List<StructureDefinition> getStructures() {
List<StructureDefinition> res = new ArrayList<>();
synchronized (lock) { // tricky, because you need to lock this as well, but it's really not in use yet
structures.listAll(res);
}
return res;
}
public String getLinkForUrl(String corePath, String url) {
if (url == null) {
return null;
@ -2206,11 +2138,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
for (StructureDefinition sd : listStructures()) {
try {
if (sd.getSnapshot().isEmpty()) {
generateSnapshot(sd);
new ContextUtilities(this).generateSnapshot(sd);
// new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "snapshot", tail(sd.getUrl())+".xml")), sd);
}
} catch (Exception e) {
// System.out.println("Unable to generate snapshot for "+tail(sd.getUrl()) +" from "+tail(sd.getBaseDefinition())+" because "+e.getMessage());
System.out.println("Unable to generate snapshot for "+tail(sd.getUrl()) +" from "+tail(sd.getBaseDefinition())+" because "+e.getMessage());
}
}
}
@ -2280,25 +2212,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
return codeSystemsUsed ;
}
public String getSpecUrl() {
String v = getVersion();
switch (VersionUtilities.getMajMin(v)) {
case "1.0" : return "http://hl7.org/fhir/DSTU1";
case "1.4" : return "http://hl7.org/fhir/DSTU2";
case "3.0" : return "http://hl7.org/fhir/STU3";
case "4.0" : return "http://hl7.org/fhir/R4";
case "4.5" : return "http://build.fhir.org";
case "5.0" : return "http://build.fhir.org";
default:
return "http://hl7.org/fhir";
}
}
public ICanonicalResourceLocator getLocator() {
public IWorkerContextManager.ICanonicalResourceLocator getLocator() {
return locator;
}
public void setLocator(ICanonicalResourceLocator locator) {
public void setLocator(IWorkerContextManager.ICanonicalResourceLocator locator) {
this.locator = locator;
}
@ -2312,31 +2230,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
txClient.setUserAgent(userAgent);
}
public List<String> getCanonicalResourceNames() {
List<String> names = new ArrayList<>();
for (StructureDefinition sd : allStructures()) {
if (sd.getKind() == StructureDefinitionKind.RESOURCE && !sd.getAbstract() && hasUrlProperty(sd)) {
names.add(sd.getType());
}
}
return names;
}
private boolean hasUrlProperty(StructureDefinition sd) {
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
if (ed.getPath().equals(sd.getType()+".url")) {
return true;
}
}
return false;
}
public IPackageLoadingTracker getPackageTracker() {
public IWorkerContextManager.IPackageLoadingTracker getPackageTracker() {
return packageTracker;
}
public IWorkerContext setPackageTracker(IPackageLoadingTracker packageTracker) {
public IWorkerContext setPackageTracker(IWorkerContextManager.IPackageLoadingTracker packageTracker) {
this.packageTracker = packageTracker;
return this;
}
}

View File

@ -0,0 +1,344 @@
package org.hl7.fhir.r5.context;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
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.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemIdentifierType;
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.NamingSystem;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.utilities.OIDUtils;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
public class ContextUtilities implements ProfileKnowledgeProvider {
private IWorkerContext context;
private boolean suppressDebugMessages;
private boolean ignoreProfileErrors;
private XVerExtensionManager xverManager;
private Map<String, String> oidCache = new HashMap<>();
public ContextUtilities(IWorkerContext context) {
super();
this.context = context;
}
public boolean isSuppressDebugMessages() {
return suppressDebugMessages;
}
public void setSuppressDebugMessages(boolean suppressDebugMessages) {
this.suppressDebugMessages = suppressDebugMessages;
}
public boolean isIgnoreProfileErrors() {
return ignoreProfileErrors;
}
public void setIgnoreProfileErrors(boolean ignoreProfileErrors) {
this.ignoreProfileErrors = ignoreProfileErrors;
}
public String oid2Uri(String oid) {
if (oid != null && oid.startsWith("urn:oid:")) {
oid = oid.substring(8);
}
if (oidCache.containsKey(oid)) {
return oidCache.get(oid);
}
String uri = OIDUtils.getUriForOid(oid);
if (uri != null) {
oidCache.put(oid, uri);
return uri;
}
CodeSystem cs = context.fetchCodeSystem("http://terminology.hl7.org/CodeSystem/v2-tables");
if (cs != null) {
for (ConceptDefinitionComponent cc : cs.getConcept()) {
for (ConceptPropertyComponent cp : cc.getProperty()) {
if (Utilities.existsInList(cp.getCode(), "v2-table-oid", "v2-cs-oid") && oid.equals(cp.getValue().primitiveValue())) {
for (ConceptPropertyComponent cp2 : cc.getProperty()) {
if ("v2-cs-uri".equals(cp2.getCode())) {
oidCache.put(oid, cp2.getValue().primitiveValue());
return cp2.getValue().primitiveValue();
}
}
}
}
}
}
for (CodeSystem css : context.fetchResourcesByType(CodeSystem.class)) {
if (("urn:oid:"+oid).equals(css.getUrl())) {
oidCache.put(oid, css.getUrl());
return css.getUrl();
}
for (Identifier id : css.getIdentifier()) {
if ("urn:ietf:rfc:3986".equals(id.getSystem()) && ("urn:oid:"+oid).equals(id.getValue())) {
oidCache.put(oid, css.getUrl());
return css.getUrl();
}
}
}
for (NamingSystem ns : context.fetchResourcesByType(NamingSystem.class)) {
if (hasOid(ns, oid)) {
uri = getUri(ns);
if (uri != null) {
oidCache.put(oid, null);
return null;
}
}
}
oidCache.put(oid, null);
return null;
}
private String getUri(NamingSystem ns) {
for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) {
if (id.getType() == NamingSystemIdentifierType.URI)
return id.getValue();
}
return null;
}
private boolean hasOid(NamingSystem ns, String oid) {
for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) {
if (id.getType() == NamingSystemIdentifierType.OID && id.getValue().equals(oid))
return true;
}
return false;
}
/**
* @return a list of the resource and type names defined for this version
*/
public List<String> getTypeNames() {
List<String> result = new ArrayList<String>();
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (sd.getKind() != StructureDefinitionKind.LOGICAL && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION)
result.add(sd.getName());
}
Collections.sort(result);
return result;
}
public String getLinkForUrl(String corePath, String url) {
if (url == null) {
return null;
}
CanonicalResource cr = context.fetchResource(CanonicalResource.class, url);
if (cr != null) {
return cr.getUserString("path");
}
if (url.equals("http://loinc.org")) {
return corePath+"loinc.html";
}
if (url.equals("http://unitsofmeasure.org")) {
return corePath+"ucum.html";
}
if (url.equals("http://snomed.info/sct")) {
return corePath+"snomed.html";
}
return null;
}
protected String tail(String url) {
if (Utilities.noString(url)) {
return "noname";
}
if (url.contains("/")) {
return url.substring(url.lastIndexOf("/")+1);
}
return url;
}
private boolean hasUrlProperty(StructureDefinition sd) {
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
if (ed.getPath().equals(sd.getType()+".url")) {
return true;
}
}
return false;
}
// -- profile services ---------------------------------------------------------
/**
* @return a list of the resource names that are canonical resources defined for this version
*/
public List<String> getCanonicalResourceNames() {
List<String> names = new ArrayList<>();
for (StructureDefinition sd : allStructures()) {
if (sd.getKind() == StructureDefinitionKind.RESOURCE && !sd.getAbstract() && hasUrlProperty(sd)) {
names.add(sd.getType());
}
}
return names;
}
/**
* @return a list of all structure definitions, with snapshots generated (if possible)
*/
public List<StructureDefinition> allStructures(){
List<StructureDefinition> result = new ArrayList<StructureDefinition>();
Set<StructureDefinition> set = new HashSet<StructureDefinition>();
for (StructureDefinition sd : getStructures()) {
if (!set.contains(sd)) {
try {
generateSnapshot(sd);
// new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "snapshot", tail(sd.getUrl())+".xml")), sd);
} catch (Exception e) {
if (!isSuppressDebugMessages()) {
System.out.println("Unable to generate snapshot for "+tail(sd.getUrl()) +" from "+tail(sd.getBaseDefinition())+" because "+e.getMessage());
if (true) {
e.printStackTrace();
}
}
}
result.add(sd);
set.add(sd);
}
}
return result;
}
/**
* @return a list of all structure definitions, without trying to generate snapshots
*/
public List<StructureDefinition> getStructures() {
return context.fetchResourcesByType(StructureDefinition.class);
}
/**
* Given a structure definition, generate a snapshot (or regenerate it)
* @param p
* @throws DefinitionException
* @throws FHIRException
*/
public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException {
generateSnapshot(p, false);
}
public void generateSnapshot(StructureDefinition p, boolean ifLogical) {
if ((!p.hasSnapshot() || isProfileNeedsRegenerate(p) ) && (ifLogical || p.getKind() != StructureDefinitionKind.LOGICAL)) {
if (!p.hasBaseDefinition())
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE___HAS_NO_BASE_AND_NO_SNAPSHOT, p.getName(), p.getUrl()));
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getBaseDefinition());
if (sd == null && "http://hl7.org/fhir/StructureDefinition/Base".equals(p.getBaseDefinition())) {
sd = ProfileUtilities.makeBaseDefinition(p.getFhirVersion());
}
if (sd == null) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE___BASE__COULD_NOT_BE_RESOLVED, p.getName(), p.getUrl(), p.getBaseDefinition()));
}
List<ValidationMessage> msgs = new ArrayList<ValidationMessage>();
List<String> errors = new ArrayList<String>();
ProfileUtilities pu = new ProfileUtilities(context, msgs, this);
pu.setAutoFixSliceNames(true);
pu.setThrowException(false);
if (xverManager == null) {
xverManager = new XVerExtensionManager(context);
}
pu.setXver(xverManager);
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) {
pu.sortDifferential(sd, p, p.getUrl(), errors, true);
}
pu.setDebug(false);
for (String err : errors)
msgs.add(new ValidationMessage(Source.ProfileValidator, IssueType.EXCEPTION, p.getUserString("path"), "Error sorting Differential: "+err, ValidationMessage.IssueSeverity.ERROR));
pu.generateSnapshot(sd, p, p.getUrl(), sd.getUserString("webroot"), p.getName());
for (ValidationMessage msg : msgs) {
if ((!ignoreProfileErrors && msg.getLevel() == ValidationMessage.IssueSeverity.ERROR) || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL)
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE___ELEMENT__ERROR_GENERATING_SNAPSHOT_, p.getName(), p.getUrl(), msg.getLocation(), msg.getMessage()));
}
if (!p.hasSnapshot())
throw new FHIRException(context.formatMessage(I18nConstants.PROFILE___ERROR_GENERATING_SNAPSHOT, p.getName(), p.getUrl()));
pu = null;
}
}
// work around the fact that some Implementation guides were published with old snapshot generators that left invalid snapshots behind.
private boolean isProfileNeedsRegenerate(StructureDefinition p) {
boolean needs = !p.hasUserData("hack.regnerated") && Utilities.existsInList(p.getUrl(), "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse");
if (needs) {
p.setUserData("hack.regnerated", "yes");
}
return needs;
}
@Override
public boolean isDatatype(String typeSimple) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isResource(String t) {
StructureDefinition sd;
try {
sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+t);
} catch (Exception e) {
return false;
}
if (sd == null)
return false;
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT)
return false;
return sd.getKind() == StructureDefinitionKind.RESOURCE;
}
@Override
public boolean hasLinkFor(String typeSimple) {
return false;
}
@Override
public String getLinkFor(String corePath, String typeSimple) {
return null;
}
@Override
public BindingResolution resolveBinding(StructureDefinition profile, ElementDefinitionBindingComponent binding, String path) {
return null;
}
@Override
public BindingResolution resolveBinding(StructureDefinition profile, String url, String path) {
return null;
}
@Override
public String getLinkForProfile(StructureDefinition profile, String url) {
return null;
}
@Override
public boolean prependLinks() {
return false;
}
}

View File

@ -87,8 +87,8 @@ import javax.annotation.Nonnull;
* implementation.
*
* The functionality it provides is
* - get access to parsers, validators, narrative builders etc
* (you can't create these directly because they need access
* - get access to canonical resources,terminology services, and validator
* (you can't create a validator directly because it needs access
* to the right context for their information)
*
* - find resources that the tools need to carry out their tasks
@ -100,10 +100,121 @@ import javax.annotation.Nonnull;
*
* @author Grahame
*/
public interface IWorkerContext {
public interface IPackageLoadingTracker {
public void packageLoaded(String pid, String version);
public interface IWorkerContext {
class ValidationResult {
private ConceptDefinitionComponent definition;
private String system;
private IssueSeverity severity;
private String message;
private TerminologyServiceErrorClass errorClass;
private String txLink;
@Override
public String toString() {
return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + message + ", errorClass="
+ errorClass + ", txLink=" + txLink + "]";
}
public ValidationResult(IssueSeverity severity, String message) {
this.severity = severity;
this.message = message;
}
public ValidationResult(String system, ConceptDefinitionComponent definition) {
this.system = system;
this.definition = definition;
}
public ValidationResult(IssueSeverity severity, String message, String system, ConceptDefinitionComponent definition) {
this.severity = severity;
this.message = message;
this.system = system;
this.definition = definition;
}
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
this.severity = severity;
this.message = message;
this.errorClass = errorClass;
}
public boolean isOk() {
return severity == null || severity == IssueSeverity.INFORMATION || severity == IssueSeverity.WARNING;
}
public String getSystem() {
return system;
}
public String getDisplay() {
return definition == null ? null : definition.getDisplay();
}
public String getCode() {
return definition == null ? null : definition.getCode();
}
public String getDefinition() {
return definition == null ? null : definition.getDefinition();
}
public ConceptDefinitionComponent asConceptDefinition() {
return definition;
}
public IssueSeverity getSeverity() {
return severity;
}
public String getMessage() {
return message;
}
public boolean IsNoService() {
return errorClass == TerminologyServiceErrorClass.NOSERVICE;
}
public TerminologyServiceErrorClass getErrorClass() {
return errorClass;
}
public ValidationResult setSeverity(IssueSeverity severity) {
this.severity = severity;
return this;
}
public ValidationResult setMessage(String message) {
this.message = message;
return this;
}
public ValidationResult setErrorClass(TerminologyServiceErrorClass errorClass) {
this.errorClass = errorClass;
return this;
}
public String getTxLink() {
return txLink;
}
public ValidationResult setTxLink(String txLink) {
this.txLink = txLink;
return this;
}
public boolean hasMessage() {
return message != null;
}
public Coding asCoding() {
if (isOk() && definition != null && definition.getCode() != null) {
return new Coding(system, definition.getCode(), definition.getDisplay());
} else {
return null;
}
}
}
public class CodingValidationRequest {
@ -223,10 +334,6 @@ public interface IWorkerContext {
}
public interface ICanonicalResourceLocator {
void findResource(Object caller, String url); // if it can be found, put it in the context
}
public interface IContextResourceLoader {
/**
* @return List of the resource types that should be loaded
@ -263,9 +370,9 @@ public interface IWorkerContext {
String getResourcePath(Resource resource);
/**
* called when a mew package is being loaded
* called when a new package is being loaded
*
* this is called by loadPacakgeAndDependencies when a new package is loaded
* this is called by loadPackageAndDependencies when a new package is loaded
* @param npm
* @return
* @throws IOException
@ -275,59 +382,22 @@ public interface IWorkerContext {
}
/**
* Get the versions of the definitions loaded in context
* Get the version of the definitions loaded in context
* This *does not* have to be 5.0 (R5) - the context can load other versions
*
* @return
*/
public String getVersion();
/**
* return the link to the base of the specification for the loaded version e.g. http://hl7.org/fhir/R4
* Get the UCUM service that provides access to units of measure reasoning services
*
* This service might not be available
*
* @return
*/
public String getSpecUrl();
// get the UCUM service (might not be available)
public UcumService getUcumService();
// -- Parsers (read and write instances) ----------------------------------------
/**
* Get a parser to read/write instances. Use the defined type (will be extended
* as further types are added, though the only currently anticipate type is RDF)
*
* XML/JSON - the standard renderers
* XHTML - render the narrative only (generate it if necessary)
*
* @param type
* @return
*/
public IParser getParser(ParserType type);
/**
* Get a parser to read/write instances. Determine the type
* from the stated type. Supported value for type:
* - the recommended MIME types
* - variants of application/xml and application/json
* - _format values xml, json
*
* @param type
* @return
*/
public IParser getParser(String type);
/**
* Get a JSON parser
*
* @return
*/
public IParser newJsonParser();
/**
* Get an XML parser
*
* @return
*/
public IParser newXmlParser();
public void setUcumService(UcumService ucumService);
/**
* Get a validator that can check whether a resource is valid
@ -358,6 +428,8 @@ public interface IWorkerContext {
* It's an error if the second form doesn't agree with class_. It's an
* error if class_ is null for the last form
*
* class can be Resource, DomainResource or CanonicalResource, which means resource of all kinds
*
* @param resource
* @param Reference
* @return
@ -379,6 +451,17 @@ public interface IWorkerContext {
*/
public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource canonicalForSource);
/**
* Fetch all the resources of a particular type. if class == (null | Resource | DomainResource | CanonicalResource) return everything
*
* @param <T>
* @param class_
* @param uri
* @param canonicalForSource
* @return
*/
public <T extends Resource> List<T> fetchResourcesByType(Class<T> class_);
/**
* Variation of fetchResource when you have a string type, and don't need the right class
*
@ -453,40 +536,6 @@ public interface IWorkerContext {
*/
public Set<String> getResourceNamesAsSet();
/**
* @return a list of the resource names that are canonical resources defined for this version
*/
public List<String> getCanonicalResourceNames();
/**
* @return a list of the resource and type names defined for this version
*/
public List<String> getTypeNames();
/**
* @return a list of all structure definitions, with snapshots generated (if possible)
*/
public List<StructureDefinition> allStructures();
/**
* @return a list of all structure definitions, without trying to generate snapshots
*/
public List<StructureDefinition> getStructures();
/**
* @return a list of all conformance resources
*/
public List<CanonicalResource> allConformanceResources();
/**
* Given a structure definition, generate a snapshot (or regenerate it)
* @param p
* @throws DefinitionException
* @throws FHIRException
*/
public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException;
public void generateSnapshot(StructureDefinition mr, boolean ifLogical);
// -- Terminology services ------------------------------------------------------
/**
@ -509,6 +558,8 @@ public interface IWorkerContext {
* return null if there isn't one (then the tool might try
* supportsSystem)
*
* This is a short cut for fetchResource(CodeSystem.class...)
*
* @param system
* @return
*/
@ -524,20 +575,14 @@ public interface IWorkerContext {
*
* in the Conformance resource
*
* Not that not all supported code systems have an available CodeSystem resource
*
* @param system
* @return
* @throws Exception
*/
public boolean supportsSystem(String system) throws TerminologyServiceException;
/**
* find concept maps for a source
* @param url
* @return
* @throws FHIRException
*/
public List<ConceptMap> findMapsForSource(String url) throws FHIRException;
/**
* ValueSet Expansion - see $expand
*
@ -574,127 +619,25 @@ public interface IWorkerContext {
*/
ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical, boolean noInactive) throws TerminologyServiceException;
/**
* get/set the locale used when creating messages
*
* todo: what's the difference?
*
* @return
*/
Locale getLocale();
void setLocale(Locale locale);
String formatMessage(String theMessage, Object... theMessageArguments);
void setValidationMessageLanguage(Locale locale);
class ValidationResult {
private ConceptDefinitionComponent definition;
private String system;
private IssueSeverity severity;
private String message;
private TerminologyServiceErrorClass errorClass;
private String txLink;
@Override
public String toString() {
return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + message + ", errorClass="
+ errorClass + ", txLink=" + txLink + "]";
}
public ValidationResult(IssueSeverity severity, String message) {
this.severity = severity;
this.message = message;
}
public ValidationResult(String system, ConceptDefinitionComponent definition) {
this.system = system;
this.definition = definition;
}
public ValidationResult(IssueSeverity severity, String message, String system, ConceptDefinitionComponent definition) {
this.severity = severity;
this.message = message;
this.system = system;
this.definition = definition;
}
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
this.severity = severity;
this.message = message;
this.errorClass = errorClass;
}
public boolean isOk() {
return severity == null || severity == IssueSeverity.INFORMATION || severity == IssueSeverity.WARNING;
}
public String getSystem() {
return system;
}
public String getDisplay() {
return definition == null ? null : definition.getDisplay();
}
public String getCode() {
return definition == null ? null : definition.getCode();
}
public String getDefinition() {
return definition == null ? null : definition.getDefinition();
}
public ConceptDefinitionComponent asConceptDefinition() {
return definition;
}
public IssueSeverity getSeverity() {
return severity;
}
public String getMessage() {
return message;
}
public boolean IsNoService() {
return errorClass == TerminologyServiceErrorClass.NOSERVICE;
}
public TerminologyServiceErrorClass getErrorClass() {
return errorClass;
}
public ValidationResult setSeverity(IssueSeverity severity) {
this.severity = severity;
return this;
}
public ValidationResult setMessage(String message) {
this.message = message;
return this;
}
public ValidationResult setErrorClass(TerminologyServiceErrorClass errorClass) {
this.errorClass = errorClass;
return this;
}
public String getTxLink() {
return txLink;
}
public ValidationResult setTxLink(String txLink) {
this.txLink = txLink;
return this;
}
public boolean hasMessage() {
return message != null;
}
public Coding asCoding() {
if (isOk() && definition != null && definition.getCode() != null) {
return new Coding(system, definition.getCode(), definition.getDisplay());
} else {
return null;
}
}
}
/**
* Access to the contexts internationalised error messages
*
* @param theMessage
* @param theMessageArguments
* @return
*/
String formatMessage(String theMessage, Object... theMessageArguments);
/**
* Validation of a code - consult the terminology infrstructure and/or service
@ -780,31 +723,32 @@ public interface IWorkerContext {
*/
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs);
/**
* See comments in ValidationContextCarrier. This is called when there might be additional value sets etc
* available in the context, but we don't want to pre-process them.
*
* @param options
* @param code
* @param vs
* @param ctxt
* @return
*/
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs, ValidationContextCarrier ctxt);
/**
* Batch validate code - reduce latency and do a bunch of codes in a single server call.
* Each is the same as a validateCode
*
* @param options
* @param codes
* @param vs
*/
public void validateCodeBatch(ValidationOptions options, List<? extends CodingValidationRequest> codes, ValueSet vs);
/**
* returns the recommended tla for the type (from the structure definitions)
*
* @param name
* @return
*/
public String getAbbreviation(String name);
/**
* translate an OID to a URI (look through known NamingSystems)
* @param code
* @return
*/
public String oid2Uri(String code);
// todo: figure these out
public Map<String, NamingSystem> getNSUrlMap();
/**
* @return true if the contxt has a terminology caching service internally
*/
public boolean hasCache();
public TranslationServices translator();
public interface ILoggingService {
public enum LogCategory {
@ -818,28 +762,30 @@ public interface IWorkerContext {
public void logMessage(String message); // status messages, always display
public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging
}
public void setLogger(@Nonnull ILoggingService logger);
public ILoggingService getLogger();
public boolean isNoTerminologyServer();
public Set<String> getCodeSystemsUsed();
public TranslationServices translator();
public List<StructureMap> listTransforms();
public StructureMap getTransform(String url);
public String getOverrideVersionNs();
public void setOverrideVersionNs(String value);
public StructureDefinition fetchTypeDefinition(String typeName);
public StructureDefinition fetchRawProfile(String url);
public int getClientRetryCount();
public IWorkerContext setClientRetryCount(int value);
public void setUcumService(UcumService ucumService);
public TimeTracker clock();
public String getLinkForUrl(String corePath, String s);
/**
* This is a short cut for fetchResource(StructureDefinition.class, ...)
* but it accepts a typename - that is, it resolves based on StructureDefinition.type
* or StructureDefinition.url
*
* @param typeName
* @return
*/
public StructureDefinition fetchTypeDefinition(String typeName);
/**
* Returns a set of keys that can be used to get binaries from this context.
* The binaries come from the loaded packages (mostly the pubpack)
*
* @return a set of binaries or null
*/
@ -860,6 +806,10 @@ public interface IWorkerContext {
*/
public byte[] getBinaryForKey(String binaryKey);
/*
* Todo: move these loaders out to IWorkerContextManager
*
*/
/**
* Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
*
@ -904,12 +854,8 @@ public interface IWorkerContext {
public boolean hasPackage(PackageVersion pack);
public PackageDetails getPackage(PackageVersion pack);
public int getClientRetryCount();
public IWorkerContext setClientRetryCount(int value);
public TimeTracker clock();
public IPackageLoadingTracker getPackageTracker();
public IWorkerContext setPackageTracker(IPackageLoadingTracker packageTracker);
public IWorkerContextManager.IPackageLoadingTracker getPackageTracker();
public IWorkerContext setPackageTracker(IWorkerContextManager.IPackageLoadingTracker packageTracker);
public PackageVersion getPackageForUrl(String url);
}

View File

@ -0,0 +1,13 @@
package org.hl7.fhir.r5.context;
public interface IWorkerContextManager {
interface IPackageLoadingTracker {
public void packageLoaded(String pid, String version);
}
interface ICanonicalResourceLocator {
void findResource(Object caller, String url); // if it can be found, put it in the context
}
}

View File

@ -93,7 +93,7 @@ import ca.uhn.fhir.parser.DataFormatException;
* very light client to connect to an open unauthenticated terminology service
*/
public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext, ProfileKnowledgeProvider {
public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext {
public static class PackageResourceLoader extends CanonicalResourceProxy {
@ -139,13 +139,11 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
private String revision;
private String date;
private IValidatorFactory validatorFactory;
private boolean ignoreProfileErrors;
private boolean progress;
private final List<String> loadedPackages = new ArrayList<>();
private boolean canNoTS;
private XVerExtensionManager xverManager;
private boolean allowLazyLoading = true;
private boolean suppressDebugMessages;
private SimpleWorkerContext() throws IOException, FHIRException {
super();
@ -551,34 +549,6 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
binaries.put(name, bytes);
}
@Override
public IParser getParser(ParserType type) {
switch (type) {
case JSON: return newJsonParser();
case XML: return newXmlParser();
default:
throw new Error(formatMessage(I18nConstants.PARSER_TYPE__NOT_SUPPORTED, type.toString()));
}
}
@Override
public IParser getParser(String type) {
if (type.equalsIgnoreCase("JSON"))
return new JsonParser();
if (type.equalsIgnoreCase("XML"))
return new XmlParser();
throw new Error(formatMessage(I18nConstants.PARSER_TYPE__NOT_SUPPORTED, type.toString()));
}
@Override
public IParser newJsonParser() {
return new JsonParser();
}
@Override
public IParser newXmlParser() {
return new XmlParser();
}
@Override
public IResourceValidator newValidator() throws FHIRException {
if (validatorFactory == null)
@ -600,68 +570,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
return result;
}
@Override
public List<String> getTypeNames() {
List<String> result = new ArrayList<String>();
for (StructureDefinition sd : listStructures()) {
if (sd.getKind() != StructureDefinitionKind.LOGICAL && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION)
result.add(sd.getName());
}
Collections.sort(result);
return result;
}
@Override
public String getAbbreviation(String name) {
return "xxx";
}
@Override
public boolean isDatatype(String typeSimple) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isResource(String t) {
StructureDefinition sd;
try {
sd = fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+t);
} catch (Exception e) {
return false;
}
if (sd == null)
return false;
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT)
return false;
return sd.getKind() == StructureDefinitionKind.RESOURCE;
}
@Override
public boolean hasLinkFor(String typeSimple) {
return false;
}
@Override
public String getLinkFor(String corePath, String typeSimple) {
return null;
}
@Override
public BindingResolution resolveBinding(StructureDefinition profile, ElementDefinitionBindingComponent binding, String path) {
return null;
}
@Override
public BindingResolution resolveBinding(StructureDefinition profile, String url, String path) {
return null;
}
@Override
public String getLinkForProfile(StructureDefinition profile, String url) {
return null;
}
public Questionnaire getQuestionnaire() {
return questionnaire;
}
@ -670,30 +579,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
this.questionnaire = questionnaire;
}
@Override
public List<StructureDefinition> allStructures() {
List<StructureDefinition> result = new ArrayList<StructureDefinition>();
Set<StructureDefinition> set = new HashSet<StructureDefinition>();
for (StructureDefinition sd : listStructures()) {
if (!set.contains(sd)) {
try {
generateSnapshot(sd);
// new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "snapshot", tail(sd.getUrl())+".xml")), sd);
} catch (Exception e) {
if (!suppressDebugMessages) {
System.out.println("Unable to generate snapshot for "+tail(sd.getUrl()) +" from "+tail(sd.getBaseDefinition())+" because "+e.getMessage());
if (true) {
e.printStackTrace();
}
}
}
result.add(sd);
set.add(sd);
}
}
return result;
}
public void loadBinariesFromFolder(String folder) throws IOException {
for (String n : new File(folder).list()) {
@ -732,15 +618,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
}
}
@Override
public boolean prependLinks() {
return false;
}
@Override
public boolean hasCache() {
return true;
}
@Override
public String getVersion() {
@ -750,7 +628,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
public List<StructureMap> findTransformsforSource(String url) {
List<StructureMap> res = new ArrayList<StructureMap>();
for (StructureMap map : listTransforms()) {
for (StructureMap map : fetchResourcesByType(StructureMap.class)) {
boolean match = false;
boolean ok = true;
for (StructureMapStructureComponent t : map.getStructure()) {
@ -779,82 +657,17 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
if (r instanceof StructureDefinition) {
StructureDefinition p = (StructureDefinition)r;
try {
generateSnapshot(p);
new ContextUtilities(this).generateSnapshot(p);
} catch (Exception e) {
// not sure what to do in this case?
if (!suppressDebugMessages) {
System.out.println("Unable to generate snapshot for "+uri+": "+e.getMessage());
}
System.out.println("Unable to generate snapshot for "+uri+": "+e.getMessage());
}
}
return r;
}
@Override
public StructureDefinition fetchRawProfile(String uri) {
StructureDefinition r = super.fetchResource(StructureDefinition.class, uri);
return r;
}
@Override
public void generateSnapshot(StructureDefinition p) throws FHIRException {
generateSnapshot(p, false);
}
@Override
public void generateSnapshot(StructureDefinition p, boolean logical) throws FHIRException {
if ((!p.hasSnapshot() || isProfileNeedsRegenerate(p) ) && (logical || p.getKind() != StructureDefinitionKind.LOGICAL)) {
if (!p.hasBaseDefinition())
throw new DefinitionException(formatMessage(I18nConstants.PROFILE___HAS_NO_BASE_AND_NO_SNAPSHOT, p.getName(), p.getUrl()));
StructureDefinition sd = fetchResource(StructureDefinition.class, p.getBaseDefinition());
if (sd == null && "http://hl7.org/fhir/StructureDefinition/Base".equals(p.getBaseDefinition())) {
sd = ProfileUtilities.makeBaseDefinition(p.getFhirVersion());
}
if (sd == null) {
throw new DefinitionException(formatMessage(I18nConstants.PROFILE___BASE__COULD_NOT_BE_RESOLVED, p.getName(), p.getUrl(), p.getBaseDefinition()));
}
List<ValidationMessage> msgs = new ArrayList<ValidationMessage>();
List<String> errors = new ArrayList<String>();
ProfileUtilities pu = new ProfileUtilities(this, msgs, this);
pu.setAutoFixSliceNames(true);
pu.setThrowException(false);
if (xverManager == null) {
xverManager = new XVerExtensionManager(this);
}
pu.setXver(xverManager);
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) {
pu.sortDifferential(sd, p, p.getUrl(), errors, true);
}
pu.setDebug(false);
for (String err : errors)
msgs.add(new ValidationMessage(Source.ProfileValidator, IssueType.EXCEPTION, p.getUserString("path"), "Error sorting Differential: "+err, ValidationMessage.IssueSeverity.ERROR));
pu.generateSnapshot(sd, p, p.getUrl(), sd.getUserString("webroot"), p.getName());
for (ValidationMessage msg : msgs) {
if ((!ignoreProfileErrors && msg.getLevel() == ValidationMessage.IssueSeverity.ERROR) || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL)
throw new DefinitionException(formatMessage(I18nConstants.PROFILE___ELEMENT__ERROR_GENERATING_SNAPSHOT_, p.getName(), p.getUrl(), msg.getLocation(), msg.getMessage()));
}
if (!p.hasSnapshot())
throw new FHIRException(formatMessage(I18nConstants.PROFILE___ERROR_GENERATING_SNAPSHOT, p.getName(), p.getUrl()));
pu = null;
}
}
// work around the fact that some Implementation guides were published with old snapshot generators that left invalid snapshots behind.
private boolean isProfileNeedsRegenerate(StructureDefinition p) {
boolean needs = !p.hasUserData("hack.regnerated") && Utilities.existsInList(p.getUrl(), "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse");
if (needs) {
p.setUserData("hack.regnerated", "yes");
}
return needs;
}
public boolean isIgnoreProfileErrors() {
return ignoreProfileErrors;
}
public void setIgnoreProfileErrors(boolean ignoreProfileErrors) {
this.ignoreProfileErrors = ignoreProfileErrors;
}
public String listMapUrls() {
return Utilities.listCanonicalUrls(transforms.keys());
@ -923,14 +736,6 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
this.allowLazyLoading = allowLazyLoading;
}
public boolean isSuppressDebugMessages() {
return suppressDebugMessages;
}
public void setSuppressDebugMessages(boolean suppressDebugMessages) {
this.suppressDebugMessages = suppressDebugMessages;
}
}

View File

@ -42,6 +42,7 @@ import java.util.Set;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.ElementDefinition;
@ -486,7 +487,7 @@ public class Element extends Base {
}
private boolean isDataType(Base v) {
return v instanceof DataType && property.getContext().getTypeNames().contains(v.fhirType());
return v instanceof DataType && new ContextUtilities(property.getContext()).getTypeNames().contains(v.fhirType());
}
@Override
@ -845,7 +846,7 @@ public class Element extends Base {
private List<ElementDefinition> children;
public ElementSortComparator(Element e, Property property) {
String tn = e.getType();
StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(tn, property.getContext().getOverrideVersionNs()));
StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(tn, null));
if (sd != null && !sd.getAbstract())
children = sd.getSnapshot().getElement();
else

View File

@ -379,7 +379,7 @@ public class JsonParser extends ParserBase {
logError(line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
} else {
String name = rt.getAsString();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, context.getOverrideVersionNs()));
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
if (sd == null) {
logError(line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL);
} else {

View File

@ -86,7 +86,7 @@ public class ObjectConverter {
if (base == null)
return null;
String tn = base.fhirType();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(tn, context.getOverrideVersionNs()));
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(tn, null));
if (sd == null)
throw new FHIRException("Unable to find definition for type "+tn);
Element res = new Element(property.getName(), property);

View File

@ -39,6 +39,7 @@ 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.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.formats.FormatUtilities;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
@ -156,7 +157,7 @@ public abstract class ParserBase {
logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);
return null;
}
for (StructureDefinition sd : context.allStructures()) {
for (StructureDefinition sd : new ContextUtilities(context).allStructures()) {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && !sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/de-")) {
if(name.equals(sd.getType()) && (ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
return sd;
@ -175,15 +176,15 @@ public abstract class ParserBase {
return null;
}
// first pass: only look at base definitions
for (StructureDefinition sd : context.getStructures()) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (sd.getUrl().equals("http://hl7.org/fhir/StructureDefinition/"+name)) {
context.generateSnapshot(sd);
new ContextUtilities(context).generateSnapshot(sd);
return sd;
}
}
for (StructureDefinition sd : context.getStructures()) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (name.equals(sd.getType()) && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
context.generateSnapshot(sd);
new ContextUtilities(context).generateSnapshot(sd);
return sd;
}
}

View File

@ -265,7 +265,7 @@ public class Property {
return false;
StructureDefinition sd = context.fetchResource(StructureDefinition.class, structure.getUrl().substring(0, structure.getUrl().lastIndexOf("/")+1)+getType(name));
if (sd == null)
sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(getType(name), context.getOverrideVersionNs()));
sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(getType(name), null));
if (sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE)
return true;
if (sd == null || sd.getKind() != StructureDefinitionKind.LOGICAL)
@ -348,7 +348,7 @@ public class Property {
assert aType.getProfile().size() == 1;
url = aType.getProfile().get(0).getValue();
} else {
url = ProfileUtilities.sdNs(t, context.getOverrideVersionNs());
url = ProfileUtilities.sdNs(t, null);
}
break;
}

View File

@ -534,7 +534,7 @@ public class XmlParser extends ParserBase {
private void parseResource(String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
org.w3c.dom.Element res = XMLUtil.getFirstChild(container);
String name = res.getLocalName();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, context.getOverrideVersionNs()));
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
if (sd == null)
throw new FHIRFormatError(context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, res.getLocalName()));
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty);

View File

@ -15,6 +15,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.formats.FormatUtilities;
import org.hl7.fhir.r5.model.Address;
import org.hl7.fhir.r5.model.Annotation;
@ -946,7 +947,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
}
if (xverManager.matchingUrl(url) && xverManager.status(url) == XVerExtensionStatus.Valid) {
ed = xverManager.makeDefinition(url);
getContext().getWorker().generateSnapshot(ed);
new ContextUtilities(getContext().getWorker()).generateSnapshot(ed);
getContext().getWorker().cacheResource(ed);
}
}

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.UUID;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept;
@ -133,7 +134,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
li.tx(opt.getValue().primitiveValue());
} else if (opt.getValue() instanceof Coding) {
Coding c = (Coding) opt.getValue();
String link = c.hasSystem() ? context.getWorker().getLinkForUrl(context.getSpecificationLink(), c.getSystem()) : null;
String link = c.hasSystem() ? new ContextUtilities(context.getWorker()).getLinkForUrl(context.getSpecificationLink(), c.getSystem()) : null;
if (link == null) {
li.tx(c.getSystem()+"#"+c.getCode());
} else {

View File

@ -27,6 +27,7 @@ import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.ExtensionHelper;
import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
@ -97,22 +98,33 @@ public class ValueSetRenderer extends TerminologyRenderer {
private List<UsedConceptMap> findReleventMaps(ValueSet vs) throws FHIRException {
List<UsedConceptMap> res = new ArrayList<UsedConceptMap>();
for (CanonicalResource md : getContext().getWorker().allConformanceResources()) {
if (md instanceof ConceptMap) {
ConceptMap cm = (ConceptMap) md;
if (isSource(vs, cm.getSourceScope())) {
ConceptMapRenderInstructions re = findByTarget(cm.getTargetScope());
if (re == null) {
re = new ConceptMapRenderInstructions(cm.present(), cm.getUrl(), false);
}
if (re != null) {
ValueSet vst = cm.hasTargetScope() ? getContext().getWorker().fetchResource(ValueSet.class, cm.hasTargetScopeCanonicalType() ? cm.getTargetScopeCanonicalType().getValue() : cm.getTargetScopeUriType().asStringValue()) : null;
res.add(new UsedConceptMap(re, vst == null ? cm.getUserString("path") : vst.getUserString("path"), cm));
}
for (ConceptMap cm : getContext().getWorker().fetchResourcesByType(ConceptMap.class)) {
if (isSource(vs, cm.getSourceScope())) {
ConceptMapRenderInstructions re = findByTarget(cm.getTargetScope());
if (re == null) {
re = new ConceptMapRenderInstructions(cm.present(), cm.getUrl(), false);
}
if (re != null) {
ValueSet vst = cm.hasTargetScope() ? getContext().getWorker().fetchResource(ValueSet.class, cm.hasTargetScopeCanonicalType() ? cm.getTargetScopeCanonicalType().getValue() : cm.getTargetScopeUriType().asStringValue()) : null;
res.add(new UsedConceptMap(re, vst == null ? cm.getUserString("path") : vst.getUserString("path"), cm));
}
}
}
return res;
// @Override
// public List<ConceptMap> findMapsForSource(String url) throws FHIRException {
// synchronized (lock) {
// List<ConceptMap> res = new ArrayList<ConceptMap>();
// for (ConceptMap map : maps.getList()) {
// if (((Reference) map.getSourceScope()).getReference().equals(url)) {
// res.add(map);
// }
// }
// return res;
// }
// }
// Map<ConceptMap, String> mymaps = new HashMap<ConceptMap, String>();
// for (ConceptMap a : context.getWorker().findMapsForSource(vs.getUrl())) {
// String url = "";
@ -1272,7 +1284,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
}
ValueSetExpansionComponent vse = null;
if (!context.isNoSlowLookup() && !getContext().getWorker().hasCache()) {
if (!context.isNoSlowLookup()) { // && !getContext().getWorker().hasCache()) { removed GG 20220107 like what is this trying to do?
try {
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false, false);
ValueSet valueset = vso.getValueset();

View File

@ -56,7 +56,7 @@ public class Resolver {
} else if (rw instanceof ElementWrappers.ResourceWrapperMetaElement) {
this.element = ((ElementWrappers.ResourceWrapperMetaElement) rw).getElement();
} else {
throw new Error("Not supported yet");
// this is not supported for now... throw new Error("Not supported yet");
}
}

View File

@ -72,6 +72,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.context.IWorkerContext;
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.CanonicalResource;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.Parameters;
@ -99,7 +100,7 @@ public class ValueSetExpansionCache implements ValueSetExpanderFactory {
vso = context.expandVS(source, false, expParams == null || !expParams.getParameterBool("excludeNested"));
if (cacheFolder != null) {
FileOutputStream s = new FileOutputStream(Utilities.path(cacheFolder, makeFileName(source.getUrl())));
context.newXmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, vso.getValueset());
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, vso.getValueset());
s.close();
}
}
@ -153,7 +154,7 @@ public class ValueSetExpansionCache implements ValueSetExpanderFactory {
if (f.getName().endsWith(".xml")) {
final FileInputStream is = new FileInputStream(f);
try {
Resource r = context.newXmlParser().setOutputStyle(OutputStyle.PRETTY).parse(is);
Resource r = new XmlParser().setOutputStyle(OutputStyle.PRETTY).parse(is);
if (r instanceof OperationOutcome) {
OperationOutcome oo = (OperationOutcome) r;
expansions.put(ToolingExtensions.getExtension(oo,VS_ID_EXT).getValue().toString(),
@ -200,7 +201,7 @@ public class ValueSetExpansionCache implements ValueSetExpanderFactory {
}
if (cacheFolder != null) {
FileOutputStream s = new FileOutputStream(Utilities.path(cacheFolder, makeFileName(md.getUrl()+"|"+md.getVersion())));
context.newXmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, md);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, md);
s.close();
}
}

View File

@ -27,6 +27,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
import org.hl7.fhir.r5.model.Base;
@ -364,7 +365,7 @@ public class FHIRPathEngine {
super();
this.worker = worker;
profileUtilities = utilities;
for (StructureDefinition sd : worker.getStructures()) {
for (StructureDefinition sd : worker.fetchResourcesByType(StructureDefinition.class)) {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.LOGICAL) {
allTypes.put(sd.getName(), sd);
}
@ -5524,22 +5525,22 @@ public class FHIRPathEngine {
m = getElementDefinition(sd, type.substring(type.indexOf("#")+1), false, expr);
if (m != null && hasDataType(m.definition)) {
if (m.fixedType != null) {
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, worker.getOverrideVersionNs()));
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, null));
if (dt == null) {
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(m.fixedType, worker.getOverrideVersionNs()), "getChildTypesByName");
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(m.fixedType, null), "getChildTypesByName");
}
sdl.add(dt);
} else
for (TypeRefComponent t : m.definition.getType()) {
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(t.getCode(), worker.getOverrideVersionNs()));
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(t.getCode(), null));
if (dt == null) {
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(t.getCode(), worker.getOverrideVersionNs()), "getChildTypesByName");
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(t.getCode(), null), "getChildTypesByName");
}
addTypeAndDescendents(sdl, dt, worker.allStructures());
addTypeAndDescendents(sdl, dt, new ContextUtilities(worker).allStructures());
// also add any descendant types
}
} else {
addTypeAndDescendents(sdl, sd, worker.allStructures());
addTypeAndDescendents(sdl, sd, new ContextUtilities(worker).allStructures());
if (type.contains("#")) {
tail = type.substring(type.indexOf("#")+1);
tail = tail.substring(tail.indexOf("."));
@ -5683,7 +5684,7 @@ public class FHIRPathEngine {
if (ed.getType().size() > 1) { // if there's more than one type, the test above would fail this
throw new Error("Internal typing issue....");
}
StructureDefinition nsd = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getType().get(0).getCode(), worker.getOverrideVersionNs()));
StructureDefinition nsd = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getType().get(0).getCode(), null));
if (nsd == null) {
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ed.getType().get(0).getCode(), "getElementDefinition");
}
@ -5901,7 +5902,7 @@ public class FHIRPathEngine {
if (ed.getTypes().get(0).hasProfile()) {
return worker.fetchResource(StructureDefinition.class, ed.getTypes().get(0).getProfile().get(0).getValue());
} else {
return worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getTypes().get(0).getCode(), worker.getOverrideVersionNs()));
return worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getTypes().get(0).getCode(), null));
}
}

View File

@ -36,6 +36,7 @@ package org.hl7.fhir.r5.utils;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
@ -96,7 +97,7 @@ public class GraphQLSchemaGenerator {
Map<String, StructureDefinition> pl = new HashMap<>();
Map<String, StructureDefinition> tl = new HashMap<>();
Map<String, String> existingTypeNames = new HashMap<>();
for (StructureDefinition sd : context.allStructures()) {
for (StructureDefinition sd : new ContextUtilities(context).allStructures()) {
if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
pl.put(sd.getName(), sd);
}

View File

@ -4,6 +4,7 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.ServiceRequest;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
public class PublicationHacker {
@ -16,7 +17,7 @@ public class PublicationHacker {
// ServiceRequest.code
if (res.getValue().contains("LOINC is (preferred)[http://build.fhir.org/terminologies.html#preferred]")) {
res.setValue(res.getValue().replace("LOINC is (preferred)[http://build.fhir.org/terminologies.html#preferred]", "LOINC is [preferred]("+Utilities.pathURL(context.getSpecUrl(), "terminologies.html#preferred)")));
res.setValue(res.getValue().replace("LOINC is (preferred)[http://build.fhir.org/terminologies.html#preferred]", "LOINC is [preferred]("+Utilities.pathURL(VersionUtilities.getSpecUrl(context.getVersion()), "terminologies.html#preferred)")));
}
if (res.getValue().contains("[here](valueset-diagnostic-requests.html)")) {
res.setValue(res.getValue().replace("[here](valueset-diagnostic-requests.html)", "here"));

View File

@ -38,6 +38,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
import org.hl7.fhir.r5.elementmodel.Element;
@ -1315,13 +1316,13 @@ public class StructureMapUtilities {
private List<StructureMap> findMatchingMaps(String value) {
List<StructureMap> res = new ArrayList<StructureMap>();
if (value.contains("*")) {
for (StructureMap sm : worker.listTransforms()) {
for (StructureMap sm : worker.fetchResourcesByType(StructureMap.class)) {
if (urlMatches(value, sm.getUrl())) {
res.add(sm);
}
}
} else {
StructureMap sm = worker.getTransform(value);
StructureMap sm = worker.fetchResource(StructureMap.class, value);
if (sm != null)
res.add(sm);
}
@ -1861,7 +1862,7 @@ public class StructureMapUtilities {
String su = conceptMapUrl;
if (conceptMapUrl.equals("http://hl7.org/fhir/ConceptMap/special-oid2uri")) {
String uri = worker.oid2Uri(src.getCode());
String uri = new ContextUtilities(worker).oid2Uri(src.getCode());
if (uri == null)
uri = "urn:oid:" + src.getCode();
if ("uri".equals(fieldToReturn))
@ -2408,7 +2409,7 @@ public class StructureMapUtilities {
private TypeDetails getParam(VariablesForProfiling vars, StructureMapGroupRuleTargetParameterComponent parameter) throws DefinitionException {
DataType p = parameter.getValue();
if (!(p instanceof IdType))
return new TypeDetails(CollectionStatus.SINGLETON, ProfileUtilities.sdNs(p.fhirType(), worker.getOverrideVersionNs()));
return new TypeDetails(CollectionStatus.SINGLETON, ProfileUtilities.sdNs(p.fhirType(), null));
else {
String n = ((IdType) p).asStringValue();
VariableForProfiling b = vars.get(VariableMode.INPUT, n);

View File

@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Manager;
@ -38,10 +39,10 @@ public class CDARoundTripTests {
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ed.xml"), "ed.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "st.xml"), "st.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
for (StructureDefinition sd : context.getStructures()) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (!sd.hasSnapshot()) {
// System.out.println("generate snapshot for " + sd.getUrl());
context.generateSnapshot(sd, true);
new ContextUtilities(context).generateSnapshot(sd, true);
}
}
}

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.r5.test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Manager;
@ -36,10 +37,10 @@ public class XmlParserTests {
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ed.xml"), "ed.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "st.xml"), "st.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
for (StructureDefinition sd : context.getStructures()) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (!sd.hasSnapshot()) {
System.out.println("generate snapshot for " + sd.getUrl());
context.generateSnapshot(sd, true);
new ContextUtilities(context).generateSnapshot(sd, true);
}
}
}

View File

@ -564,5 +564,18 @@ public class VersionUtilities {
return refVer.equals(v);
}
public static String getSpecUrl(String v) {
switch (getMajMin(v)) {
case "1.0" : return "http://hl7.org/fhir/DSTU1";
case "1.4" : return "http://hl7.org/fhir/DSTU2";
case "3.0" : return "http://hl7.org/fhir/STU3";
case "4.0" : return "http://hl7.org/fhir/R4";
case "4.5" : return "http://build.fhir.org";
case "5.0" : return "http://build.fhir.org";
default:
return "http://hl7.org/fhir";
}
}
}

View File

@ -28,8 +28,8 @@ CodeSystem_CS_VS_IncludeDetails = CodeSystem {0} has an ''all system'' value set
CodeSystem_CS_VS_Invalid = CodeSystem {0} has an ''all system'' value set of {1}, but doesn''t have a single include
CODESYSTEM_CS_VS_EXP_MISMATCH = CodeSystem {0} has an ''all system'' value set of {1}, but it is an expansion with the wrong number of concepts (found {2}, expected {3})
CodeSystem_CS_VS_WrongSystem = CodeSystem {0} has an ''all system'' value set of {1}, but doesn''t have a matching system ({2})
Extension_EXTP_Context_Wrong = The extension {0} is not allowed to be used at this point (allowed = {1}; this element is [{2})
Extension_EXTM_Context_Wrong = The modifier extension {0} is not allowed to be used at this point (allowed = {1}; this element is [{2})
Extension_EXTP_Context_Wrong = The extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
Extension_EXTM_Context_Wrong = The modifier extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
Extension_EXT_Count_Mismatch = Extensions count mismatch: expected {0} but found {1}
Extension_EXT_Count_NotFound = Extension count mismatch: unable to find extension: {0}
Extension_EXT_Fixed_Banned = No extensions allowed, as the specified fixed value doesn''t contain any extensions

View File

@ -36,6 +36,7 @@ import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
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.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.JsonParser;
@ -1035,7 +1036,7 @@ public class BaseValidator implements IValidationContextResourceLoader {
return null;
case Valid:
StructureDefinition defn = xverDefn(url);
context.generateSnapshot(defn);
new ContextUtilities(context).generateSnapshot(defn);
context.cacheResource(defn);
return defn;
default:
@ -1061,7 +1062,7 @@ public class BaseValidator implements IValidationContextResourceLoader {
break;
case Valid:
StructureDefinition ex = xverDefn(url);
context.generateSnapshot(ex);
new ContextUtilities(context).generateSnapshot(ex);
context.cacheResource(ex);
return ex;
default:

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.validation;
import lombok.Getter;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ImplementationGuide;
@ -62,7 +63,7 @@ public class Scanner {
List<String> refs = new ArrayList<>();
ValidatorUtils.parseSources(sources, refs, getContext());
List<ScanOutputItem> res = new ArrayList();
List<ScanOutputItem> res = new ArrayList<>();
for (String ref : refs) {
Content cnt = getIgLoader().loadContent(ref, "validate", false);
@ -94,7 +95,7 @@ public class Scanner {
}
}
Set<String> done = new HashSet<>();
for (StructureDefinition sd : getContext().allStructures()) {
for (StructureDefinition sd : new ContextUtilities(getContext()).allStructures()) {
if (!done.contains(sd.getUrl())) {
done.add(sd.getUrl());
if (sd.getUrl().startsWith(canonical) && rt.equals(sd.getType())) {

View File

@ -12,10 +12,12 @@ import org.hl7.fhir.convertors.txClient.TerminologyClientFactory;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ICanonicalResourceLocator;
import org.hl7.fhir.r5.context.IWorkerContext.IPackageLoadingTracker;
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
import org.hl7.fhir.r5.context.IWorkerContextManager;
import org.hl7.fhir.r5.context.IWorkerContextManager.ICanonicalResourceLocator;
import org.hl7.fhir.r5.context.IWorkerContextManager.IPackageLoadingTracker;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SystemOutLoggingService;
import org.hl7.fhir.r5.elementmodel.Element;
@ -135,7 +137,7 @@ POSSIBILITY OF SUCH DAMAGE.
* @author Grahame Grieve
*/
@Accessors(chain = true)
public class ValidationEngine implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IPackageInstaller, IPackageLoadingTracker {
public class ValidationEngine implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IPackageInstaller, IWorkerContextManager.IPackageLoadingTracker {
@Getter @Setter private SimpleWorkerContext context;
@Getter @Setter private Map<String, byte[]> binaries = new HashMap<>();
@ -151,7 +153,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
@Getter @Setter private boolean debug = false;
@Getter @Setter private IValidatorResourceFetcher fetcher;
@Getter @Setter private IValidationPolicyAdvisor policyAdvisor;
@Getter @Setter private ICanonicalResourceLocator locator;
@Getter @Setter private IWorkerContextManager.ICanonicalResourceLocator locator;
@Getter @Setter private boolean assumeValidRestReferences;
@Getter @Setter private boolean noExtensibleBindingMessages;
@Getter @Setter private boolean noUnicodeBiDiControlChars;
@ -497,7 +499,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
}
public StructureMap compile(String mapUri) throws FHIRException, IOException {
StructureMap map = context.getTransform(mapUri);
StructureMap map = context.fetchResource(StructureMap.class, mapUri);
return map;
}
@ -505,7 +507,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
List<Base> outputs = new ArrayList<>();
StructureMapUtilities scu = new StructureMapUtilities(context, new TransformSupportServices(outputs, mapLog, context));
org.hl7.fhir.r5.elementmodel.Element src = Manager.parseSingle(context, new ByteArrayInputStream(source), cntType);
StructureMap map = context.getTransform(mapUri);
StructureMap map = context.fetchResource(StructureMap.class, mapUri);
if (map == null) throw new Error("Unable to find map " + mapUri + " (Known Maps = " + context.listMapUrls() + ")");
org.hl7.fhir.r5.elementmodel.Element resource = getTargetResourceFromStructureMap(map);
scu.transform(null, src, map, resource);
@ -524,7 +526,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
if (targetTypeUrl == null) throw new FHIRException("Unable to determine resource URL for target type");
StructureDefinition structureDefinition = null;
for (StructureDefinition sd : this.context.getStructures()) {
for (StructureDefinition sd : this.context.fetchResourcesByType(StructureDefinition.class)) {
if (sd.getUrl().equalsIgnoreCase(targetTypeUrl)) {
structureDefinition = sd;
break;
@ -639,7 +641,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
}
public void prepare() {
for (StructureDefinition sd : context.allStructures()) {
for (StructureDefinition sd : new ContextUtilities(context).allStructures()) {
try {
makeSnapshot(sd);
} catch (Exception e) {
@ -757,7 +759,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
String url = getMapId(type, targetVer);
List<Base> outputs = new ArrayList<Base>();
StructureMapUtilities scu = new StructureMapUtilities(context, new TransformSupportServices(outputs, mapLog, context));
StructureMap map = context.getTransform(url);
StructureMap map = context.fetchResource(StructureMap.class, url);
if (map == null)
throw new Error("Unable to find map " + url + " (Known Maps = " + context.listMapUrls() + ")");
org.hl7.fhir.r5.elementmodel.Element resource = getTargetResourceFromStructureMap(map);

View File

@ -4,7 +4,8 @@ import com.google.gson.JsonObject;
import org.hl7.fhir.convertors.txClient.TerminologyClientFactory;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ICanonicalResourceLocator;
import org.hl7.fhir.r5.context.IWorkerContextManager;
import org.hl7.fhir.r5.context.IWorkerContextManager.ICanonicalResourceLocator;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.ElementDefinition;
@ -36,7 +37,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IValidationPolicyAdvisor, ICanonicalResourceLocator {
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IWorkerContextManager.ICanonicalResourceLocator {
List<String> mappingsUris = new ArrayList<>();
private FilesystemPackageCacheManager pcm;

View File

@ -6,6 +6,7 @@ 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.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
import org.hl7.fhir.r5.elementmodel.Manager;
@ -242,13 +243,14 @@ public class ValidationService {
if (cliContext.getMap() == null)
throw new Exception("Must provide a map when doing a transform");
try {
List<StructureDefinition> structures = validator.getContext().allStructures();
ContextUtilities cu = new ContextUtilities(validator.getContext());
List<StructureDefinition> structures = cu.allStructures();
for (StructureDefinition sd : structures) {
if (!sd.hasSnapshot()) {
if (sd.getKind() != null && sd.getKind() == StructureDefinitionKind.LOGICAL) {
validator.getContext().generateSnapshot(sd, true);
cu.generateSnapshot(sd, true);
} else {
validator.getContext().generateSnapshot(sd, false);
cu.generateSnapshot(sd, false);
}
}
}
@ -277,13 +279,14 @@ public class ValidationService {
if (cliContext.getOutput() == null)
throw new Exception("Must provide an output name when compiling a transform");
try {
List<StructureDefinition> structures = validator.getContext().allStructures();
ContextUtilities cu = new ContextUtilities(validator.getContext());
List<StructureDefinition> structures = cu.allStructures();
for (StructureDefinition sd : structures) {
if (!sd.hasSnapshot()) {
if (sd.getKind() != null && sd.getKind() == StructureDefinitionKind.LOGICAL) {
validator.getContext().generateSnapshot(sd, true);
cu.generateSnapshot(sd, true);
} else {
validator.getContext().generateSnapshot(sd, false);
cu.generateSnapshot(sd, false);
}
}
}

View File

@ -60,6 +60,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
import org.hl7.fhir.r5.elementmodel.Element;
@ -1483,7 +1484,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
res.getCodingFirstRep().setCode(list.get(0).primitiveValue());
} else if ("Coding.system[fmt:OID]".equals(m)) {
String oid = list.get(0).primitiveValue();
String url = context.oid2Uri(oid);
String url = new ContextUtilities(context).oid2Uri(oid);
if (url != null) {
res.getCodingFirstRep().setSystem(url);
} else {
@ -1522,7 +1523,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
res.setCode(list.get(0).primitiveValue());
} else if ("Coding.system[fmt:OID]".equals(m)) {
String oid = list.get(0).primitiveValue();
String url = context.oid2Uri(oid);
String url = new ContextUtilities(context).oid2Uri(oid);
if (url != null) {
res.setSystem(url);
} else {
@ -5939,7 +5940,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
public void checkAllInvariants() {
for (StructureDefinition sd : context.allStructures()) {
for (StructureDefinition sd : new ContextUtilities(context).allStructures()) {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
for (ElementDefinitionConstraintComponent inv : ed.getConstraint()) {

View File

@ -10,6 +10,7 @@ import java.util.stream.Stream;
import javax.xml.parsers.ParserConfigurationException;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.formats.IParser;
@ -64,10 +65,10 @@ public class StructureMappingTests {
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ed.xml"), "ed.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "st.xml"), "st.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
for (StructureDefinition sd : context.getStructures()) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (!sd.hasSnapshot()) {
System.out.println("generate snapshot for " + sd.getUrl());
context.generateSnapshot(sd, true);
new ContextUtilities(context).generateSnapshot(sd, true);
}
}
if (context.getValidatorFactory() == null) {

View File

@ -33,6 +33,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
@ -325,7 +326,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
String contents = TestingUtilities.loadTestResource("validator", filename);
CanonicalResource mr = (CanonicalResource) loadResource(filename, contents);
if (mr instanceof StructureDefinition) {
val.getContext().generateSnapshot((StructureDefinition) mr, true);
new ContextUtilities(val.getContext()).generateSnapshot((StructureDefinition) mr, true);
}
val.getContext().cacheResource(mr);
}

View File

@ -19,7 +19,7 @@
<properties>
<hapi_fhir_version>5.4.0</hapi_fhir_version>
<validator_test_case_version>1.1.115</validator_test_case_version>
<validator_test_case_version>1.1.116-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>