Merge branch 'master' of ssh://github.com/hapifhir/org.hl7.fhir.core into cli_cleanup
This commit is contained in:
commit
a31ce48e6e
|
@ -588,7 +588,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// hack around a problem in R4 definitions (somewhere?)
|
||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
|
||||
mm.setMap(mm.getMap().trim());
|
||||
if (mm.hasMap()) {
|
||||
mm.setMap(mm.getMap().trim());
|
||||
}
|
||||
}
|
||||
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
|
||||
if (s.hasSource()) {
|
||||
|
|
|
@ -154,5 +154,8 @@ public class Base64BinaryType extends PrimitiveType<byte[]> implements IPrimitiv
|
|||
return ca.uhn.fhir.util.ElementUtil.isEmpty(id, extension) && !hasValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String primitiveValue() {
|
||||
return encode(myValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
|||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.formats.FormatUtilities;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
|
@ -126,6 +127,7 @@ import org.hl7.fhir.r5.model.DiagnosticReport;
|
|||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Dosage;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Encounter;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
|
||||
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
|
||||
|
@ -137,7 +139,10 @@ import org.hl7.fhir.r5.model.IdType;
|
|||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||
import org.hl7.fhir.r5.model.InstantType;
|
||||
import org.hl7.fhir.r5.model.ListResource;
|
||||
import org.hl7.fhir.r5.model.ListResource.ListResourceEntryComponent;
|
||||
import org.hl7.fhir.r5.model.Meta;
|
||||
import org.hl7.fhir.r5.model.MetadataResource;
|
||||
import org.hl7.fhir.r5.model.Narrative;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
|
@ -145,6 +150,7 @@ import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterCom
|
|||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||
import org.hl7.fhir.r5.model.Patient;
|
||||
import org.hl7.fhir.r5.model.Period;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
|
@ -380,6 +386,8 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
return generate(rcontext, (OperationDefinition) r); // Maintainer = Grahame
|
||||
} else if (r instanceof StructureDefinition) {
|
||||
return generate(rcontext, (StructureDefinition) r, outputTracker); // Maintainer = Grahame
|
||||
} else if (r instanceof List) {
|
||||
return generate(rcontext, (ListResource) r); // Maintainer = Grahame
|
||||
} else if (r instanceof ImplementationGuide) {
|
||||
return generate(rcontext, (ImplementationGuide) r); // Maintainer = Lloyd (until Grahame wants to take over . . . :))
|
||||
} else if (r instanceof DiagnosticReport) {
|
||||
|
@ -432,21 +440,67 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
public BaseWrapper value();
|
||||
}
|
||||
|
||||
private interface ResourceWrapper {
|
||||
private interface WrapperBase {
|
||||
public boolean has(String name);
|
||||
public Base get(String name) throws UnsupportedEncodingException, FHIRException, IOException;
|
||||
public List<BaseWrapper> children(String name) throws UnsupportedEncodingException, FHIRException, IOException;
|
||||
public List<PropertyWrapper> children();
|
||||
}
|
||||
|
||||
private interface ResourceWrapper extends WrapperBase {
|
||||
public List<ResourceWrapper> getContained();
|
||||
public String getId();
|
||||
public XhtmlNode getNarrative() throws FHIRFormatError, IOException, FHIRException;
|
||||
public String getName();
|
||||
public List<PropertyWrapper> children();
|
||||
public void display(XhtmlNode x);
|
||||
}
|
||||
|
||||
private interface BaseWrapper {
|
||||
private interface BaseWrapper extends WrapperBase {
|
||||
public Base getBase() throws UnsupportedEncodingException, IOException, FHIRException;
|
||||
public List<PropertyWrapper> children();
|
||||
public PropertyWrapper getChildByName(String tail);
|
||||
}
|
||||
|
||||
private class BaseWrapperElement implements BaseWrapper {
|
||||
private abstract class WrapperBaseImpl implements WrapperBase {
|
||||
@Override
|
||||
public boolean has(String name) {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
return p.hasValues();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base get(String name) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
if (p.hasValues()) {
|
||||
return p.getValues().get(0).getBase();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseWrapper> children(String name) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
List<BaseWrapper> res = new ArrayList<>();
|
||||
for (BaseWrapper b : p.getValues()) {
|
||||
res.add(b);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class BaseWrapperElement extends WrapperBaseImpl implements BaseWrapper {
|
||||
private Element element;
|
||||
private String type;
|
||||
private StructureDefinition structure;
|
||||
|
@ -594,7 +648,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
}
|
||||
|
||||
private class BaseWrapperMetaElement implements BaseWrapper {
|
||||
private class BaseWrapperMetaElement extends WrapperBaseImpl implements BaseWrapper {
|
||||
private org.hl7.fhir.r5.elementmodel.Element element;
|
||||
private String type;
|
||||
private StructureDefinition structure;
|
||||
|
@ -652,7 +706,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
|
||||
}
|
||||
public class ResourceWrapperMetaElement implements ResourceWrapper {
|
||||
public class ResourceWrapperMetaElement extends WrapperBaseImpl implements ResourceWrapper {
|
||||
private org.hl7.fhir.r5.elementmodel.Element wrapped;
|
||||
private List<ResourceWrapper> list;
|
||||
private List<PropertyWrapper> list2;
|
||||
|
@ -712,6 +766,11 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(XhtmlNode x) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
}
|
||||
|
||||
private class PropertyWrapperMetaElement implements PropertyWrapper {
|
||||
|
@ -781,7 +840,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
}
|
||||
|
||||
private class ResourceWrapperElement implements ResourceWrapper {
|
||||
private class ResourceWrapperElement extends WrapperBaseImpl implements ResourceWrapper {
|
||||
|
||||
private Element wrapped;
|
||||
private StructureDefinition definition;
|
||||
|
@ -847,6 +906,13 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void display(XhtmlNode x) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
}
|
||||
|
||||
private class PropertyWrapperDirect implements PropertyWrapper {
|
||||
|
@ -917,7 +983,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private class BaseWrapperDirect implements BaseWrapper {
|
||||
private class BaseWrapperDirect extends WrapperBaseImpl implements BaseWrapper {
|
||||
private Base wrapped;
|
||||
private List<PropertyWrapper> list;
|
||||
|
||||
|
@ -955,7 +1021,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
}
|
||||
|
||||
public class ResourceWrapperDirect implements ResourceWrapper {
|
||||
public class ResourceWrapperDirect extends WrapperBaseImpl implements ResourceWrapper {
|
||||
private Resource wrapped;
|
||||
|
||||
public ResourceWrapperDirect(Resource wrapped) {
|
||||
|
@ -1006,6 +1072,17 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(XhtmlNode x) {
|
||||
if (wrapped instanceof CanonicalResource) {
|
||||
x.tx(((CanonicalResource) wrapped).present());
|
||||
} else if (wrapped instanceof Patient) {
|
||||
displayPatient(x, (Patient) wrapped);
|
||||
} else if (wrapped instanceof Encounter) {
|
||||
displayEncounter(x, (Encounter) wrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ResourceWithReference {
|
||||
|
@ -1126,26 +1203,30 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
}
|
||||
|
||||
// dom based version, for build program
|
||||
public String generate(org.hl7.fhir.r5.elementmodel.Element er, boolean showCodeDetails, ITypeParser parser) throws IOException, FHIRException {
|
||||
public String generate(org.hl7.fhir.r5.elementmodel.Element er, boolean showCodeDetails, ITypeParser parser) throws IOException, FHIRException, EOperationOutcome {
|
||||
return generate(null, er, showCodeDetails, parser);
|
||||
}
|
||||
|
||||
public String generate(ResourceContext rcontext, org.hl7.fhir.r5.elementmodel.Element er, boolean showCodeDetails, ITypeParser parser) throws IOException, FHIRException {
|
||||
public String generate(ResourceContext rcontext, org.hl7.fhir.r5.elementmodel.Element er, boolean showCodeDetails, ITypeParser parser) throws IOException, FHIRException, EOperationOutcome {
|
||||
if (rcontext == null)
|
||||
rcontext = new ResourceContext(null, er);
|
||||
this.parser = parser;
|
||||
|
||||
ResourceWrapperMetaElement resw = new ResourceWrapperMetaElement(er);
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
try {
|
||||
ResourceWrapperMetaElement resw = new ResourceWrapperMetaElement(er);
|
||||
BaseWrapperMetaElement base = new BaseWrapperMetaElement(er, null, er.getProperty().getStructure(), er.getProperty().getDefinition());
|
||||
base.children();
|
||||
generateByProfile(resw, er.getProperty().getStructure(), base, er.getProperty().getStructure().getSnapshot().getElement(), er.getProperty().getDefinition(), base.children, x, er.fhirType(), showCodeDetails, 0, rcontext);
|
||||
if ("List".equals(resw.getName())) {
|
||||
generateList(x, resw);
|
||||
} else {
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
try {
|
||||
BaseWrapperMetaElement base = new BaseWrapperMetaElement(er, null, er.getProperty().getStructure(), er.getProperty().getDefinition());
|
||||
base.children();
|
||||
generateByProfile(resw, er.getProperty().getStructure(), base, er.getProperty().getStructure().getSnapshot().getElement(), er.getProperty().getDefinition(), base.children, x, er.fhirType(), showCodeDetails, 0, rcontext);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
x.para().b().setAttribute("style", "color: maroon").tx("Exception generating Narrative: "+e.getMessage());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
x.para().b().setAttribute("style", "color: maroon").tx("Exception generating Narrative: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
inject(er, x, NarrativeStatus.GENERATED);
|
||||
return new XhtmlComposer(XhtmlComposer.XML, pretty).compose(x);
|
||||
|
@ -4370,6 +4451,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
return displayRange((Range) type);
|
||||
return null;
|
||||
}
|
||||
|
||||
private String gen(Extension extension) throws DefinitionException {
|
||||
if (extension.getValue() instanceof CodeType)
|
||||
return ((CodeType) extension.getValue()).getValue();
|
||||
|
@ -4379,6 +4461,21 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
throw new DefinitionException("Unhandled type "+extension.getValue().getClass().getName());
|
||||
}
|
||||
|
||||
public String gen(Reference ref) {
|
||||
if (ref == null)
|
||||
return null;
|
||||
if (ref.hasDisplay()) {
|
||||
return ref.getDisplay();
|
||||
}
|
||||
if (ref.hasReference()) {
|
||||
return ref.getReference();
|
||||
}
|
||||
if (ref.hasIdentifier()) {
|
||||
return displayIdentifier(ref.getIdentifier());
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
public String gen(CodeableConcept code) {
|
||||
if (code == null)
|
||||
return null;
|
||||
|
@ -4406,6 +4503,189 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
inject(sd, x, NarrativeStatus.GENERATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean generate(ResourceContext rcontext, ListResource list) throws EOperationOutcome, FHIRException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
if (list.hasTitle()) {
|
||||
x.h2().tx(list.getTitle());
|
||||
}
|
||||
XhtmlNode t = x.table("clstu");
|
||||
XhtmlNode tr = t.tr();
|
||||
if (list.hasDate()) {
|
||||
tr.td().tx("Date: "+list.getDate().toLocaleString());
|
||||
}
|
||||
if (list.hasMode()) {
|
||||
tr.td().tx("Mode: "+list.getMode().getDisplay());
|
||||
}
|
||||
if (list.hasStatus()) {
|
||||
tr.td().tx("Status: "+list.getStatus().getDisplay());
|
||||
}
|
||||
if (list.hasCode()) {
|
||||
tr.td().tx("Code: "+gen(list.getCode()));
|
||||
}
|
||||
tr = t.tr();
|
||||
if (list.hasSubject()) {
|
||||
shortForRef(tr.td().tx("Subject: "), list.getSubject());
|
||||
}
|
||||
if (list.hasEncounter()) {
|
||||
shortForRef(tr.td().tx("Encounter: "), list.getEncounter());
|
||||
}
|
||||
if (list.hasSource()) {
|
||||
shortForRef(tr.td().tx("Source: "), list.getEncounter());
|
||||
}
|
||||
if (list.hasOrderedBy()) {
|
||||
tr.td().tx("Order: "+gen(list.getOrderedBy()));
|
||||
}
|
||||
for (Annotation a : list.getNote()) {
|
||||
renderAnnotation(a, x);
|
||||
}
|
||||
boolean flag = false;
|
||||
boolean deleted = false;
|
||||
boolean date = false;
|
||||
for (ListResourceEntryComponent e : list.getEntry()) {
|
||||
flag = flag || e.hasFlag();
|
||||
deleted = deleted || e.hasDeleted();
|
||||
date = date || e.hasDate();
|
||||
}
|
||||
t = x.table("grid");
|
||||
tr = t.tr().style("backgound-color: #eeeeee");
|
||||
tr.td().b().tx("Items");
|
||||
if (date) {
|
||||
tr.td().tx("Date");
|
||||
}
|
||||
if (flag) {
|
||||
tr.td().tx("Flag");
|
||||
}
|
||||
if (deleted) {
|
||||
tr.td().tx("Deleted");
|
||||
}
|
||||
for (ListResourceEntryComponent e : list.getEntry()) {
|
||||
tr = t.tr();
|
||||
shortForRef(tr.td(), e.getItem());
|
||||
if (date) {
|
||||
tr.td().tx(e.hasDate() ? e.getDate().toLocaleString() : "");
|
||||
}
|
||||
if (flag) {
|
||||
tr.td().tx(e.hasFlag() ? gen(e.getFlag()) : "");
|
||||
}
|
||||
if (deleted) {
|
||||
tr.td().tx(e.hasDeleted() ? Boolean.toString(e.getDeleted()) : "");
|
||||
}
|
||||
}
|
||||
inject(list, x, NarrativeStatus.GENERATED);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean generateList(XhtmlNode x, ResourceWrapper list) throws EOperationOutcome, FHIRException, IOException {
|
||||
if (list.has("title")) {
|
||||
x.h2().tx(list.get("title").primitiveValue());
|
||||
}
|
||||
XhtmlNode t = x.table("clstu");
|
||||
XhtmlNode tr = t.tr();
|
||||
if (list.has("date")) {
|
||||
tr.td().tx("Date: "+list.get("date").dateTimeValue().toHumanDisplay());
|
||||
}
|
||||
if (list.has("mode")) {
|
||||
tr.td().tx("Mode: "+list.get("mode").primitiveValue());
|
||||
}
|
||||
if (list.has("status")) {
|
||||
tr.td().tx("Status: "+list.get("status").primitiveValue());
|
||||
}
|
||||
if (list.has("code")) {
|
||||
tr.td().tx("Code: "+genCC(list.get("code")));
|
||||
}
|
||||
tr = t.tr();
|
||||
if (list.has("subject")) {
|
||||
shortForRef(tr.td().tx("Subject: "), list.get("subject"));
|
||||
}
|
||||
if (list.has("encounter")) {
|
||||
shortForRef(tr.td().tx("Encounter: "), list.get("encounter"));
|
||||
}
|
||||
if (list.has("source")) {
|
||||
shortForRef(tr.td().tx("Source: "), list.get("encounter"));
|
||||
}
|
||||
if (list.has("orderedBy")) {
|
||||
tr.td().tx("Order: "+genCC(list.get("orderedBy")));
|
||||
}
|
||||
// for (Annotation a : list.getNote()) {
|
||||
// renderAnnotation(a, x);
|
||||
// }
|
||||
boolean flag = false;
|
||||
boolean deleted = false;
|
||||
boolean date = false;
|
||||
for (BaseWrapper e : list.children("entry")) {
|
||||
flag = flag || e.has("flag");
|
||||
deleted = deleted || e.has("deleted");
|
||||
date = date || e.has("date");
|
||||
}
|
||||
t = x.table("grid");
|
||||
tr = t.tr().style("backgound-color: #eeeeee");
|
||||
tr.td().b().tx("Items");
|
||||
if (date) {
|
||||
tr.td().tx("Date");
|
||||
}
|
||||
if (flag) {
|
||||
tr.td().tx("Flag");
|
||||
}
|
||||
if (deleted) {
|
||||
tr.td().tx("Deleted");
|
||||
}
|
||||
for (BaseWrapper e : list.children("entry")) {
|
||||
tr = t.tr();
|
||||
shortForRef(tr.td(), e.get("item"));
|
||||
if (date) {
|
||||
tr.td().tx(e.has("date") ? e.get("date").dateTimeValue().toHumanDisplay() : "");
|
||||
}
|
||||
if (flag) {
|
||||
tr.td().tx(e.has("flag") ? genCC(e.get("flag")) : "");
|
||||
}
|
||||
if (deleted) {
|
||||
tr.td().tx(e.has("deleted") ? e.get("deleted").primitiveValue() : "");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String genCC(Base base) {
|
||||
if (base instanceof org.hl7.fhir.r5.elementmodel.Element) {
|
||||
CodeableConcept cc = ObjectConverter.readAsCodeableConcept((org.hl7.fhir.r5.elementmodel.Element) base);
|
||||
return gen(cc);
|
||||
} else if (base instanceof CodeableConcept) {
|
||||
return gen((CodeableConcept) base);
|
||||
} else {
|
||||
return "todo";
|
||||
}
|
||||
}
|
||||
|
||||
private void shortForRef(XhtmlNode x, Reference ref) {
|
||||
ResourceWithReference r = resolver.resolve(ref.getReference());
|
||||
if (r == null) {
|
||||
x.tx(gen(ref));
|
||||
} else {
|
||||
r.resource.display(x.ah(r.reference));
|
||||
}
|
||||
}
|
||||
|
||||
private void shortForRef(XhtmlNode x, Base ref) {
|
||||
String disp = ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null;
|
||||
if (ref.getChildByName("reference").hasValues()) {
|
||||
String url = ref.getChildByName("reference").getValues().get(0).primitiveValue();
|
||||
ResourceWithReference r = resolver.resolve(url);
|
||||
if (r == null) {
|
||||
if (disp == null) {
|
||||
disp = url;
|
||||
}
|
||||
x.tx(disp);
|
||||
} else {
|
||||
r.resource.display(x.ah(r.reference));
|
||||
}
|
||||
} else if (disp != null) {
|
||||
x.tx(disp);
|
||||
} else {
|
||||
x.tx("??");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean generate(ResourceContext rcontext, ImplementationGuide ig) throws EOperationOutcome, FHIRException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.h2().addText(ig.getName());
|
||||
|
@ -5163,6 +5443,13 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
return codeSystemPropList;
|
||||
}
|
||||
|
||||
public void displayEncounter(XhtmlNode x, Encounter wrapped) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
|
||||
public void displayPatient(XhtmlNode x, Patient wrapped) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -461,5 +461,13 @@ public class I18nConstants {
|
|||
public static final String MEASURE_M_GROUP_STRATA = "MEASURE_M_GROUP_STRATA";
|
||||
public static final String MEASURE_M_LIB_UNKNOWN = "MEASURE_M_LIB_UNKNOWN";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = "TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE";
|
||||
|
||||
public static final String MEASURE_MR_SCORE_PROHIBITED_RT = "MEASURE_MR_SCORE_PROHIBITED_RT";
|
||||
public static final String MEASURE_MR_SCORE_PROHIBITED_MS = "MEASURE_MR_SCORE_PROHIBITED_MS";
|
||||
public static final String MEASURE_MR_SCORE_REQUIRED = "MEASURE_MR_SCORE_REQUIRED";
|
||||
public static final String MEASURE_MR_M_SCORING_UNK = "MEASURE_MR_M_SCORING_UNK";
|
||||
public static final String MEASURE_MR_SCORE_UNIT_PROHIBITED = "MEASURE_MR_SCORE_UNIT_PROHIBITED";
|
||||
public static final String MEASURE_MR_SCORE_VALUE_REQUIRED = "MEASURE_MR_SCORE_VALUE_REQUIRED";
|
||||
public static final String MEASURE_MR_SCORE_VALUE_INVALID_01 = "MEASURE_MR_SCORE_VALUE_INVALID_01";
|
||||
public static final String MEASURE_MR_SCORE_FIXED = "MEASURE_MR_SCORE_FIXED";
|
||||
public static final String MEASURE_MR_SCORE_UNIT_REQUIRED = "MEASURE_MR_SCORE_UNIT_REQUIRED";
|
||||
}
|
|
@ -460,4 +460,13 @@ MEASURE_M_GROUP_POP_NO_CODE = A measure group population should have a code when
|
|||
MEASURE_M_GROUP_STRATA_NO_CODE = A measure group stratifier should have a code when there is more than one population
|
||||
MEASURE_M_GROUP_STRATA_COMP_NO_CODE = A measure group stratifier component should have a code when there is more than one population
|
||||
MEASURE_M_LIB_UNKNOWN = The Library {0} could not be resolved, so expression validation may not be correct
|
||||
TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = Canonical URLs must be absolute URLs if they are not fragment references ({0})
|
||||
TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = Canonical URLs must be absolute URLs if they are not fragment references ({0})
|
||||
MEASURE_MR_SCORE_PROHIBITED_RT = No measureScore when the type of the report is ''data-collection''
|
||||
MEASURE_MR_SCORE_PROHIBITED_MS = No measureScore when the scoring of the mesage is ''cohort''
|
||||
MEASURE_MR_SCORE_REQUIRED = A measureScore is required when the Measure.scoring={0}
|
||||
MEASURE_MR_M_SCORING_UNK = The scoring system in this measure is unknown, so the measureScore values cannot be checked
|
||||
MEASURE_MR_SCORE_UNIT_PROHIBITED = A measureScore for this Measure Scoring ({0}) should not have units
|
||||
MEASURE_MR_SCORE_VALUE_REQUIRED = A value is required when the Measure.scoring={0}
|
||||
MEASURE_MR_SCORE_VALUE_INVALID_01 = The value is invalid - it must be between 0 and 1
|
||||
MEASURE_MR_SCORE_FIXED = This value is fixed by the Measure to ''{0]''
|
||||
MEASURE_MR_SCORE_UNIT_REQUIRED = A unit should be present when the scoring type is {0}
|
|
@ -3946,7 +3946,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
String id = element.getChildValue("id");
|
||||
if (!Utilities.noString(id)) {
|
||||
rule(errors, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), !stack.getIds().containsKey(id) || stack.getIds().get(id) == element, I18nConstants.DUPLICATE_ID, id);
|
||||
if (stack.getIds().containsKey(id) && stack.getIds().get(id) != element) {
|
||||
rule(errors, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.DUPLICATE_ID, id);
|
||||
}
|
||||
stack.getIds().put(id, element);
|
||||
}
|
||||
if (definition.getPath().equals("StructureDefinition.snapshot")) {
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package org.hl7.fhir.validation.instance.type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.Library;
|
||||
import org.hl7.fhir.r5.model.Measure;
|
||||
import org.hl7.fhir.r5.model.Measure.MeasureGroupComponent;
|
||||
|
||||
public class MeasureContext {
|
||||
|
||||
|
||||
private List<Library> libs = new ArrayList<>();
|
||||
private Measure measure;
|
||||
private Element report;
|
||||
|
||||
public MeasureContext() {
|
||||
|
||||
}
|
||||
public MeasureContext(Measure measure, Element report) {
|
||||
this.measure = measure;
|
||||
this.report = report;
|
||||
}
|
||||
|
||||
public void seeLibrary(Library l) {
|
||||
libs.add(l);
|
||||
}
|
||||
|
||||
public List<MeasureGroupComponent> groups() {
|
||||
return measure.getGroup();
|
||||
}
|
||||
|
||||
public Measure measure() {
|
||||
return measure;
|
||||
}
|
||||
|
||||
public String reportType() {
|
||||
return report.getChildValue("type");
|
||||
}
|
||||
public String scoring() {
|
||||
return measure.getScoring().getCodingFirstRep().getCode();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -33,9 +35,10 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
|||
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
||||
import org.hl7.fhir.validation.BaseValidator;
|
||||
import org.hl7.fhir.validation.TimeTracker;
|
||||
import org.hl7.fhir.validation.instance.utils.MeasureContext;
|
||||
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
||||
|
||||
import net.sf.saxon.tree.tiny.LargeStringBuffer;
|
||||
|
||||
public class MeasureValidator extends BaseValidator {
|
||||
|
||||
public MeasureValidator(IWorkerContext context, TimeTracker timeTracker) {
|
||||
|
@ -71,7 +74,6 @@ public class MeasureValidator extends BaseValidator {
|
|||
warning(errors, IssueType.REQUIRED, p.line(), p.col(), ns2.getLiteralPath(), pl.size() == 1 || p.hasChild("code"), I18nConstants.MEASURE_M_GROUP_POP_NO_CODE);
|
||||
c1++;
|
||||
}
|
||||
warning(errors, IssueType.REQUIRED, group.line(), group.col(), ns.getLiteralPath(), group.hasChildren("stratifier"), I18nConstants.MEASURE_M_GROUP_STRATA);
|
||||
c1 = 0;
|
||||
List<Element> stl = group.getChildrenByName("stratifier");
|
||||
for (Element st : stl) {
|
||||
|
@ -127,9 +129,13 @@ public class MeasureValidator extends BaseValidator {
|
|||
if (hint(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), measure != null, I18nConstants.MEASURE_MR_M_NONE)) {
|
||||
long t = System.nanoTime();
|
||||
Measure msrc = measure.startsWith("#") ? loadMeasure(element, measure.substring(1)) : context.fetchResource(Measure.class, measure);
|
||||
timeTracker.sd(t, System.nanoTime());
|
||||
if (warning(errors, IssueType.REQUIRED, m.line(), m.col(), stack.getLiteralPath(), msrc != null, I18nConstants.MEASURE_MR_M_NOTFOUND, measure)) {
|
||||
boolean inComplete = !"complete".equals(element.getNamedChildValue("status"));
|
||||
validateMeasureReportGroups(hostContext, msrc, errors, element, stack, inComplete);
|
||||
MeasureContext mc = new MeasureContext(msrc, element);
|
||||
NodeStack ns = stack.push(m, -1, m.getProperty().getDefinition(), m.getProperty().getDefinition());
|
||||
hint(errors, IssueType.BUSINESSRULE, m.line(), m.col(), ns.getLiteralPath(), Utilities.existsInList(mc.scoring(), "proportion", "ratio", "continuous-variable", "cohort"), I18nConstants.MEASURE_MR_M_SCORING_UNK);
|
||||
validateMeasureReportGroups(hostContext, mc, errors, element, stack, inComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,41 +184,41 @@ public class MeasureValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroups(ValidatorHostContext hostContext, Measure m, List<ValidationMessage> errors, Element mr, NodeStack stack, boolean inProgress) {
|
||||
private void validateMeasureReportGroups(ValidatorHostContext hostContext, MeasureContext m, List<ValidationMessage> errors, Element mr, NodeStack stack, boolean inProgress) {
|
||||
NarrativeGenerator gen = new NarrativeGenerator(null, null, context);
|
||||
List<MeasureGroupComponent> groups = new ArrayList<MeasureGroupComponent>();
|
||||
|
||||
List<Element> glist = mr.getChildrenByName("group");
|
||||
|
||||
if (glist.size() == 1 && m.getGroup().size() == 1) {
|
||||
if (glist.size() == 1 && m.groups().size() == 1) {
|
||||
// if there's only one group, it can be ((and usually is) anonymous)
|
||||
// but we still check that the code, if both have one, is consistent.
|
||||
Element mrg = glist.get(0);
|
||||
NodeStack ns = stack.push(mrg, 0, mrg.getProperty().getDefinition(), mrg.getProperty().getDefinition());
|
||||
if (m.getGroupFirstRep().hasCode() && mrg.hasChild("code")) {
|
||||
if (m.groups().get(0).hasCode() && mrg.hasChild("code")) {
|
||||
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(mrg.getNamedChild("code"));
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), hasUseableCode(cc), I18nConstants.MEASURE_MR_GRP_NO_USABLE_CODE)) {
|
||||
rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), cc.matches(m.getGroupFirstRep().getCode()), I18nConstants.MEASURE_MR_GRP_NO_WRONG_CODE, gen.gen(cc), gen.gen(m.getGroupFirstRep().getCode()));
|
||||
rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), cc.matches(m.groups().get(0).getCode()), I18nConstants.MEASURE_MR_GRP_NO_WRONG_CODE, gen.gen(cc), gen.gen(m.groups().get(0).getCode()));
|
||||
}
|
||||
}
|
||||
validateMeasureReportGroup(hostContext, m.getGroupFirstRep(), errors, mr, mrg, ns, inProgress, gen);
|
||||
validateMeasureReportGroup(hostContext, m, m.groups().get(0), errors, mrg, ns, inProgress, gen);
|
||||
} else {
|
||||
int i = 0;
|
||||
for (Element mrg : glist) {
|
||||
NodeStack ns = stack.push(mrg, i, mrg.getProperty().getDefinition(), mrg.getProperty().getDefinition());
|
||||
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(mrg.getNamedChild("code"));
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), cc != null, I18nConstants.MEASURE_MR_GRP_NO_CODE)) {
|
||||
MeasureGroupComponent mg = getGroupForCode(cc, m);
|
||||
MeasureGroupComponent mg = getGroupForCode(cc, m.measure());
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), mg != null, I18nConstants.MEASURE_MR_GRP_UNK_CODE)) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), !groups.contains(mg), I18nConstants.MEASURE_MR_GRP_DUPL_CODE)) {
|
||||
groups.add(mg);
|
||||
validateMeasureReportGroup(hostContext, mg, errors, mr, mrg, ns, inProgress, gen);
|
||||
validateMeasureReportGroup(hostContext, m, mg, errors, mrg, ns, inProgress, gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for (MeasureGroupComponent mg : m.getGroup()) {
|
||||
for (MeasureGroupComponent mg : m.groups()) {
|
||||
if (!groups.contains(mg)) {
|
||||
rule(errors, IssueType.BUSINESSRULE, mr.line(), mr.col(), stack.getLiteralPath(), groups.contains(mg), I18nConstants.MEASURE_MR_GRP_MISSING_BY_CODE, gen.gen(mg.getCode()));
|
||||
}
|
||||
|
@ -220,14 +226,99 @@ public class MeasureValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroup(ValidatorHostContext hostContext, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mr, Element mrg, NodeStack ns, boolean inProgress, NarrativeGenerator gen) {
|
||||
validateMeasureReportGroupPopulations(hostContext, mg, errors, mr, mrg, ns, inProgress, gen);
|
||||
// validate the score
|
||||
validateMeasureReportGroupStratifiers(hostContext, mg, errors, mr, mrg, ns, inProgress, gen);
|
||||
// validate the stratifiers
|
||||
private void validateMeasureReportGroup(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mrg, NodeStack ns, boolean inProgress, NarrativeGenerator gen) {
|
||||
validateMeasureReportGroupPopulations(hostContext, m, mg, errors, mrg, ns, inProgress, gen);
|
||||
validateScore(hostContext, m, errors, mrg, ns, inProgress, gen);
|
||||
validateMeasureReportGroupStratifiers(hostContext, m, mg, errors, mrg, ns, inProgress, gen);
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroupPopulations(ValidatorHostContext hostContext, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mr, Element mrg, NodeStack stack, boolean inProgress, NarrativeGenerator gen) {
|
||||
private void validateScore(ValidatorHostContext hostContext, MeasureContext m, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress, NarrativeGenerator gen) {
|
||||
Element ms = mrg.getNamedChild("measureScore");
|
||||
// first, we check MeasureReport.type
|
||||
if ("data-collection".equals(m.reportType())) {
|
||||
banned(errors, stack, ms, I18nConstants.MEASURE_MR_SCORE_PROHIBITED_RT);
|
||||
} else if ("cohort".equals(m.scoring())) {
|
||||
// cohort - there is no measure score
|
||||
banned(errors, stack, ms, I18nConstants.MEASURE_MR_SCORE_PROHIBITED_MS);
|
||||
} else if (Utilities.existsInList(m.scoring(), "proportion", "ratio", "continuous-variable")) {
|
||||
if (rule(errors, IssueType.REQUIRED, mrg.line(), mrg.col(), stack.getLiteralPath(), ms != null, I18nConstants.MEASURE_MR_SCORE_REQUIRED, m.scoring())) {
|
||||
NodeStack ns = stack.push(ms, -1, ms.getProperty().getDefinition(), ms.getProperty().getDefinition());
|
||||
Element v = ms.getNamedChild("value");
|
||||
if ("proportion".equals(m.scoring())) {
|
||||
// proportion - score is a unitless number from 0 ... 1
|
||||
banned(errors, ns, ms, "unit", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
|
||||
banned(errors, ns, ms, "system", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
|
||||
banned(errors, ns, ms, "code", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
|
||||
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED)) {
|
||||
try {
|
||||
BigDecimal dec = new BigDecimal(v.primitiveValue());
|
||||
NodeStack nsv = ns.push(v, -1, v.getProperty().getDefinition(), v.getProperty().getDefinition());
|
||||
rule(errors, IssueType.REQUIRED, v.line(), v.col(), nsv.getLiteralPath(), dec.compareTo(new BigDecimal(0)) >= 0 && dec.compareTo(new BigDecimal(1)) <= 0, I18nConstants.MEASURE_MR_SCORE_VALUE_INVALID_01);
|
||||
} catch (Exception e) {
|
||||
// nothing - will have caused an error elsewhere
|
||||
}
|
||||
}
|
||||
} else if ("ratio".equals(m.scoring())) {
|
||||
// ratio - score is a number with no value constraints, and maybe with a unit (perhaps constrained by extension)
|
||||
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED)) {
|
||||
Element unit = ms.getNamedChild("code");
|
||||
Coding c = m.measure().hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-unit") ? (Coding) m.measure().getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-unit").getValue() : null;
|
||||
if (unit != null) {
|
||||
if (c != null) {
|
||||
NodeStack nsc = ns.push(unit, -1, unit.getProperty().getDefinition(), unit.getProperty().getDefinition());
|
||||
rule(errors, IssueType.CODEINVALID, unit.line(), unit.col(), nsc.getLiteralPath(), c.getCode().equals(unit.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getCode());
|
||||
Element system = ms.getNamedChild("system");
|
||||
if (system == null) {
|
||||
NodeStack nss = system == null ? ns : ns.push(system, -1, system.getProperty().getDefinition(), system.getProperty().getDefinition());
|
||||
rule(errors, IssueType.CODEINVALID, system.line(), system.col(), nss.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
|
||||
} else {
|
||||
rule(errors, IssueType.CODEINVALID, ms.line(), ms.col(), ns.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
|
||||
}
|
||||
}
|
||||
} else if (c != null) {
|
||||
rule(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_FIXED, gen.gen(c));
|
||||
} else {
|
||||
warning(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_UNIT_REQUIRED, "ratio");
|
||||
}
|
||||
}
|
||||
} else if ("continuous-variable".equals(m.scoring())) {
|
||||
// continuous-variable - score is a quantity with a unit per the extension
|
||||
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED)) {
|
||||
Element unit = ms.getNamedChild("code");
|
||||
Coding c = m.measure().hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-unit") ? (Coding) m.measure().getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-unit").getValue() : null;
|
||||
if (unit != null) {
|
||||
if (c != null) {
|
||||
NodeStack nsc = ns.push(unit, -1, unit.getProperty().getDefinition(), unit.getProperty().getDefinition());
|
||||
rule(errors, IssueType.CODEINVALID, unit.line(), unit.col(), nsc.getLiteralPath(), c.getCode().equals(unit.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getCode());
|
||||
Element system = ms.getNamedChild("system");
|
||||
if (system == null) {
|
||||
NodeStack nss = system == null ? ns : ns.push(system, -1, system.getProperty().getDefinition(), system.getProperty().getDefinition());
|
||||
rule(errors, IssueType.CODEINVALID, system.line(), system.col(), nss.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
|
||||
} else {
|
||||
rule(errors, IssueType.CODEINVALID, ms.line(), ms.col(), ns.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
|
||||
}
|
||||
}
|
||||
} else if (c != null) {
|
||||
rule(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_FIXED, gen.gen(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // else do nothing - there's a hint elsewhere
|
||||
}
|
||||
}
|
||||
|
||||
private void banned(List<ValidationMessage> errors, NodeStack stack, Element parent, String childName, String msgId, Object... params) {
|
||||
Element child = parent.getNamedChild(childName);
|
||||
banned(errors, stack, child, msgId, params);
|
||||
}
|
||||
|
||||
private void banned(List<ValidationMessage> errors, NodeStack stack, Element e, String msgId, Object... params) {
|
||||
if (e != null) {
|
||||
NodeStack ns = stack.push(e, -1, e.getProperty().getDefinition(), e.getProperty().getDefinition());
|
||||
rule(errors, IssueType.BUSINESSRULE, e.line(), e.col(), ns.getLiteralPath(), false, msgId, params);
|
||||
}
|
||||
}
|
||||
private void validateMeasureReportGroupPopulations(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress, NarrativeGenerator gen) {
|
||||
// there must be a population for each population defined in the measure, and no 4others.
|
||||
List<MeasureGroupPopulationComponent> pops = new ArrayList<MeasureGroupPopulationComponent>();
|
||||
List<Element> plist = mrg.getChildrenByName("population");
|
||||
|
@ -241,7 +332,7 @@ public class MeasureValidator extends BaseValidator {
|
|||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), mgp != null, I18nConstants.MEASURE_MR_GRP_POP_UNK_CODE)) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), !pops.contains(mgp), I18nConstants.MEASURE_MR_GRP_POP_DUPL_CODE)) {
|
||||
pops.add(mgp);
|
||||
validateMeasureReportGroupPopulation(hostContext, mgp, errors, mr, mrgp, ns, inProgress);
|
||||
validateMeasureReportGroupPopulation(hostContext, m, mgp, errors, mrgp, ns, inProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,9 +345,9 @@ public class MeasureValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroupPopulation(ValidatorHostContext hostContext, MeasureGroupPopulationComponent mgp, List<ValidationMessage> errors, Element mr, Element mrgp, NodeStack ns, boolean inProgress) {
|
||||
private void validateMeasureReportGroupPopulation(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupPopulationComponent mgp, List<ValidationMessage> errors, Element mrgp, NodeStack ns, boolean inProgress) {
|
||||
List<Element> sr = mrgp.getChildrenByName("subjectResults");
|
||||
if ("subject-list".equals(mr.getChildValue("type"))) {
|
||||
if ("subject-list".equals(m.reportType())) {
|
||||
try {
|
||||
int c = Integer.parseInt(mrgp.getChildValue("count"));
|
||||
rule(errors, IssueType.BUSINESSRULE, mrgp.line(), mrgp.col(), ns.getLiteralPath(), c == sr.size(), I18nConstants.MEASURE_MR_GRP_POP_COUNT_MISMATCH, c, sr.size());
|
||||
|
@ -269,7 +360,7 @@ public class MeasureValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroupStratifiers(ValidatorHostContext hostContext, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mr, Element mrg, NodeStack stack, boolean inProgress, NarrativeGenerator gen) {
|
||||
private void validateMeasureReportGroupStratifiers(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress, NarrativeGenerator gen) {
|
||||
// there must be a population for each population defined in the measure, and no 4others.
|
||||
List<MeasureGroupStratifierComponent> strats = new ArrayList<>();
|
||||
List<Element> slist = mrg.getChildrenByName("stratifier");
|
||||
|
@ -283,7 +374,7 @@ public class MeasureValidator extends BaseValidator {
|
|||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), mgs != null, I18nConstants.MEASURE_MR_GRP_POP_UNK_CODE)) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), !strats.contains(mgs), I18nConstants.MEASURE_MR_GRP_POP_DUPL_CODE)) {
|
||||
strats.add(mgs);
|
||||
validateMeasureReportGroupStratifier(hostContext, mgs, errors, mr, mrgs, ns, inProgress);
|
||||
validateMeasureReportGroupStratifier(hostContext, m, mgs, errors, mrgs, ns, inProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +387,7 @@ public class MeasureValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateMeasureReportGroupStratifier(ValidatorHostContext hostContext, MeasureGroupStratifierComponent mgs, List<ValidationMessage> errors, Element mr, Element mrgs, NodeStack ns, boolean inProgress) {
|
||||
private void validateMeasureReportGroupStratifier(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupStratifierComponent mgs, List<ValidationMessage> errors, Element mrgs, NodeStack ns, boolean inProgress) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package org.hl7.fhir.validation.instance.utils;
|
||||
|
||||
import org.hl7.fhir.r5.model.Library;
|
||||
|
||||
public class MeasureContext {
|
||||
|
||||
public void seeLibrary(Library l) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue