Merge pull request #568 from aehrc/feature/dstu2_1_profile_paths
Correct paths to profiles and valuesets/codesystems
This commit is contained in:
commit
54376a54c6
|
@ -72,9 +72,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/v3-codesystems.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/valueset/v3-codesystems.xml");
|
||||
|
||||
myCodeSystems = codeSystems;
|
||||
myValueSets = valueSets;
|
||||
|
@ -91,7 +91,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
|
||||
|
||||
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
|
@ -210,9 +210,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
if (structureDefinitions == null) {
|
||||
structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-others.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu2016may/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu2016may/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu2016may/profile/profiles-others.xml");
|
||||
|
||||
myStructureDefinitions = structureDefinitions;
|
||||
}
|
||||
|
@ -227,9 +227,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
if (cs.hasCaseSensitive()) {
|
||||
caseSensitive = cs.getCaseSensitive();
|
||||
}
|
||||
|
||||
|
||||
CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
|
||||
|
||||
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
if (theCaseSensitive == false) {
|
||||
code = code.toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,13 +31,18 @@ import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptReferenceComponent;
|
|||
import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.dstu2016may.terminologies.ValueSetExpander;
|
||||
import org.hl7.fhir.dstu2016may.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.dstu2016may.terminologies.ValueSetExpanderFactory;
|
||||
import org.hl7.fhir.dstu2016may.terminologies.ValueSetExpanderSimple;
|
||||
import org.hl7.fhir.dstu2016may.utils.IWorkerContext;
|
||||
import org.hl7.fhir.dstu2016may.validation.IResourceValidator;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public final class HapiWorkerContext implements IWorkerContext {
|
||||
public final class HapiWorkerContext implements IWorkerContext, ValueSetExpanderFactory {
|
||||
private final FhirContext myCtx;
|
||||
private Map<String, Resource> myFetchedResourceCache = new HashMap<String, Resource>();
|
||||
private IValidationSupport myValidationSupport;
|
||||
|
@ -201,8 +206,8 @@ public final class HapiWorkerContext implements IWorkerContext {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
boolean caseSensitive = true;
|
||||
if (isNotBlank(theSystem)) {
|
||||
CodeSystem system = fetchCodeSystem(theSystem);
|
||||
|
@ -259,10 +264,27 @@ public final class HapiWorkerContext implements IWorkerContext {
|
|||
return new ValidationResult(IssueSeverity.ERROR, "Unknown code[" + theCode + "] in system[" + theSystem + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpander getExpander() {
|
||||
ValueSetExpanderSimple retVal = new ValueSetExpanderSimple(this, this);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet theSource, boolean theCacheOk) {
|
||||
throw new UnsupportedOperationException();
|
||||
ValueSetExpansionOutcome vso;
|
||||
try {
|
||||
vso = getExpander().expand(theSource);
|
||||
} catch (InvalidRequestException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new InternalErrorException(e);
|
||||
}
|
||||
if (vso.getError() != null) {
|
||||
throw new InvalidRequestException(vso.getError());
|
||||
} else {
|
||||
return vso;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,13 +25,13 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
public abstract class ParserBase {
|
||||
|
||||
interface IErrorNotifier {
|
||||
|
||||
|
||||
}
|
||||
public enum ValidationPolicy { NONE, QUICK, EVERYTHING }
|
||||
|
||||
public static boolean isPrimitive(String code) {
|
||||
return Utilities.existsInList(code,
|
||||
"xhtml", "boolean", "integer", "string", "decimal", "uri", "base64Binary", "instant", "date", "dateTime",
|
||||
return Utilities.existsInList(code,
|
||||
"xhtml", "boolean", "integer", "string", "decimal", "uri", "base64Binary", "instant", "date", "dateTime",
|
||||
"time", "code", "oid", "id", "markdown", "unsignedInt", "positiveInt", "xhtml", "base64Binary");
|
||||
}
|
||||
|
||||
|
@ -49,12 +49,12 @@ public abstract class ParserBase {
|
|||
this.policy = policy;
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
|
||||
public abstract Element parse(InputStream stream) throws Exception;
|
||||
|
||||
public abstract void compose(Element e, OutputStream destination, OutputStyle style, String base) throws Exception;
|
||||
|
||||
|
||||
|
||||
public void logError(int line, int col, String path, IssueType type, String message, IssueSeverity level) throws FHIRFormatError {
|
||||
if (policy == ValidationPolicy.EVERYTHING) {
|
||||
ValidationMessage msg = new ValidationMessage(Source.InstanceValidator, type, line, col, path, message, level);
|
||||
|
@ -62,8 +62,8 @@ public abstract class ParserBase {
|
|||
} else if (level == IssueSeverity.FATAL || (level == IssueSeverity.ERROR && policy == ValidationPolicy.QUICK))
|
||||
throw new FHIRFormatError(message+String.format(" at line %d col %d", line, col));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError {
|
||||
if (ns == null) {
|
||||
logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no namespace)", IssueSeverity.FATAL);
|
||||
|
@ -74,7 +74,7 @@ public abstract class ParserBase {
|
|||
return null;
|
||||
}
|
||||
for (StructureDefinition sd : context.allStructures()) {
|
||||
if (name.equals(sd.getId())) {
|
||||
if (name.equals(sd.getIdElement().getIdPart())) {
|
||||
if((ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
|
||||
return sd;
|
||||
String sns = ToolingExtensions.readStringExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
|
@ -92,7 +92,7 @@ public abstract class ParserBase {
|
|||
return null;
|
||||
}
|
||||
for (StructureDefinition sd : context.allStructures()) {
|
||||
if (name.equals(sd.getId())) {
|
||||
if (name.equals(sd.getIdElement().getIdPart())) {
|
||||
return sd;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public abstract class ParserBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected List<Property> getChildProperties(Property property, String elementName, String statedType) throws DefinitionException {
|
||||
ElementDefinition ed = property.getDefinition();
|
||||
StructureDefinition sd = property.getStructure();
|
||||
|
@ -128,12 +128,12 @@ public abstract class ParserBase {
|
|||
if (t == null && ToolingExtensions.hasExtension(ed, "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaultype"))
|
||||
t = ToolingExtensions.readStringExtension(ed, "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaultype");
|
||||
boolean ok = false;
|
||||
for (TypeRefComponent tr : ed.getType())
|
||||
if (tr.getCode().equals(t))
|
||||
for (TypeRefComponent tr : ed.getType())
|
||||
if (tr.getCode().equals(t))
|
||||
ok = true;
|
||||
if (!ok)
|
||||
throw new DefinitionException("Type '"+t+"' is not an acceptable type for '"+elementName+"' on property "+property.getDefinition().getPath());
|
||||
|
||||
|
||||
} else {
|
||||
t = elementName.substring(tail(ed.getPath()).length() - 3);
|
||||
if (isPrimitive(lowFirst(t)))
|
||||
|
|
|
@ -20460,7 +20460,7 @@
|
|||
<key value="dom-3"/>
|
||||
<severity value="error"/>
|
||||
<human value="If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource"/>
|
||||
<expression value="contained.select(('#'+id in $context.descendents().reference).not()).empty()"/>
|
||||
<expression value="contained.select(('#'+id in %resource.descendents().reference).not()).empty()"/>
|
||||
<xpath value="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))"/>
|
||||
</constraint>
|
||||
<constraint>
|
||||
|
@ -20649,7 +20649,7 @@
|
|||
<key value="dom-3"/>
|
||||
<severity value="error"/>
|
||||
<human value="If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource"/>
|
||||
<expression value="contained.select(('#'+id in $context.descendents().reference).not()).empty()"/>
|
||||
<expression value="contained.select(('#'+id in %resource.descendents().reference).not()).empty()"/>
|
||||
<xpath value="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))"/>
|
||||
</constraint>
|
||||
<constraint>
|
||||
|
@ -121071,7 +121071,7 @@
|
|||
<key value="obs-7"/>
|
||||
<severity value="error"/>
|
||||
<human value="Component code SHALL not be same as observation code"/>
|
||||
<expression value="component.where(code = $context.code).empty()"/>
|
||||
<expression value="component.where(code = %resource.code).empty()"/>
|
||||
<xpath value="not(exists(f:component/f:code)) or count(for $coding in f:code/f:coding return parent::*/f:component/f:code/f:coding[f:code/@value=$coding/f:code/@value and f:system/@value=$coding/f:system/@value])=0"/>
|
||||
</constraint>
|
||||
<mapping>
|
||||
|
@ -122307,7 +122307,7 @@
|
|||
<key value="obs-7"/>
|
||||
<severity value="error"/>
|
||||
<human value="Component code SHALL not be same as observation code"/>
|
||||
<expression value="component.where(code = $context.code).empty()"/>
|
||||
<expression value="component.where(code = %resource.code).empty()"/>
|
||||
<xpath value="not(exists(f:component/f:code)) or count(for $coding in f:code/f:coding return parent::*/f:component/f:code/f:coding[f:code/@value=$coding/f:code/@value and f:system/@value=$coding/f:system/@value])=0"/>
|
||||
</constraint>
|
||||
<mapping>
|
||||
|
@ -154515,7 +154515,7 @@
|
|||
<key value="sdf-8"/>
|
||||
<severity value="error"/>
|
||||
<human value="In any snapshot or differential, all the elements except the first have to have a path that starts with the path of the first + ".""/>
|
||||
<expression value="snapshot.element.tail().all(path.startsWith($context.snapshot.element.first().path+'.')) and differential.element.tail().all(path.startsWith($context.differential.element.first().path+'.'))"/>
|
||||
<expression value="snapshot.element.tail().all(path.startsWith(%resource.snapshot.element.first().path+'.')) and differential.element.tail().all(path.startsWith(%resource.differential.element.first().path+'.'))"/>
|
||||
<xpath value="string-join(for $elementName in f:*[self::f:snapshot or self::f:differential]/f:element[position()>1]/f:path/@value return if (starts-with($elementName, concat($elementName/ancestor::f:element/parent::f:*/f:element[1]/f:path/@value, '.'))) then '' else $elementName,'')=''"/>
|
||||
</constraint>
|
||||
<constraint>
|
||||
|
@ -155580,7 +155580,7 @@
|
|||
<key value="sdf-8"/>
|
||||
<severity value="error"/>
|
||||
<human value="In any snapshot or differential, all the elements except the first have to have a path that starts with the path of the first + ".""/>
|
||||
<expression value="snapshot.element.tail().all(path.startsWith($context.snapshot.element.first().path+'.')) and differential.element.tail().all(path.startsWith($context.differential.element.first().path+'.'))"/>
|
||||
<expression value="snapshot.element.tail().all(path.startsWith(%resource.snapshot.element.first().path+'.')) and differential.element.tail().all(path.startsWith(%resource.differential.element.first().path+'.'))"/>
|
||||
<xpath value="string-join(for $elementName in f:*[self::f:snapshot or self::f:differential]/f:element[position()>1]/f:path/@value return if (starts-with($elementName, concat($elementName/ancestor::f:element/parent::f:*/f:element[1]/f:path/@value, '.'))) then '' else $elementName,'')=''"/>
|
||||
</constraint>
|
||||
<constraint>
|
||||
|
|
|
@ -4681,7 +4681,7 @@
|
|||
<key value="ref-1"/>
|
||||
<severity value="error"/>
|
||||
<human value="SHALL have a local reference if the resource is provided inline"/>
|
||||
<expression value="reference.startsWith('#').not() or ($context.reference.substring(1).trace('url') in $resource.contained.id.trace('ids'))"/>
|
||||
<expression value="reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))"/>
|
||||
<xpath value="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])"/>
|
||||
</constraint>
|
||||
<mapping>
|
||||
|
@ -4779,7 +4779,7 @@
|
|||
<key value="ref-1"/>
|
||||
<severity value="error"/>
|
||||
<human value="SHALL have a local reference if the resource is provided inline"/>
|
||||
<expression value="reference.startsWith('#').not() or ($context.reference.substring(1).trace('url') in $resource.contained.id.trace('ids'))"/>
|
||||
<expression value="reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))"/>
|
||||
<xpath value="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])"/>
|
||||
</constraint>
|
||||
<mapping>
|
||||
|
|
Loading…
Reference in New Issue