2023 12 gg r6 ccda q (#1519)
* Fix for missing warnings around bundle link validation * Fix using wrong resource type when validating constraints in data type definitions (R6) * Fix NPE in validator processing CCDA examples * Handle all initial value types when rendering Questionnaires --------- Co-authored-by: Grahame Grieve <grahameg@gmail.ccom>
This commit is contained in:
parent
031c5690d8
commit
1249aa4294
|
@ -749,7 +749,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private void renderReference(XhtmlNode x, Reference ref) {
|
||||
protected void renderReference(XhtmlNode x, Reference ref) {
|
||||
if (ref.hasDisplay()) {
|
||||
x.tx(ref.getDisplay());
|
||||
} else if (ref.hasReference()) {
|
||||
|
@ -1199,7 +1199,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private String displayIdentifier(Identifier ii) {
|
||||
protected String displayIdentifier(Identifier ii) {
|
||||
String s = Utilities.noString(ii.getValue()) ? "?ngen-9?" : ii.getValue();
|
||||
NamingSystem ns = context.getContext().getNSUrlMap().get(ii.getSystem());
|
||||
if (ns != null) {
|
||||
|
@ -1528,6 +1528,11 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected void renderQuantity(HierarchicalTableGenerator gen, List<Piece> pieces, Quantity q, boolean showCodeDetails) {
|
||||
pieces.add(gen.new Piece(null, displayQuantity(q), null));
|
||||
}
|
||||
|
||||
public String displayRange(Range q) {
|
||||
if (!q.hasLow() && !q.hasHigh())
|
||||
return "?";
|
||||
|
|
|
@ -350,8 +350,14 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
defn.getPieces().add(gen.new Piece(null, " = ", null));
|
||||
if (v.getValue().isPrimitive()) {
|
||||
defn.getPieces().add(gen.new Piece(null, v.getValue().primitiveValue(), null));
|
||||
} else {
|
||||
} else if (v.hasValueCoding()) {
|
||||
renderCoding(gen, defn.getPieces(), v.getValueCoding());
|
||||
} else if (v.hasValueQuantity()) {
|
||||
renderQuantity(gen, defn.getPieces(), v.getValueQuantity(), false);
|
||||
} else if (v.hasValueReference()) {
|
||||
renderReference(q, gen, defn.getPieces(), v.getValueReference(), true);
|
||||
} else if (v.hasValueAttachment()) {
|
||||
// renderAttachment(gen, defn.getPieces(), v.getValueAttachment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -528,8 +534,14 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
defn.getPieces().add(gen.new Piece(null, " = ", null));
|
||||
if (v.getValue().isPrimitive()) {
|
||||
defn.getPieces().add(gen.new Piece(null, v.getValue().primitiveValue(), null));
|
||||
} else {
|
||||
} else if (v.hasValueCoding()) {
|
||||
renderCoding(gen, defn.getPieces(), v.getValueCoding());
|
||||
} else if (v.hasValueQuantity()) {
|
||||
renderQuantity(gen, defn.getPieces(), v.getValueQuantity(), false);
|
||||
} else if (v.hasValueReference()) {
|
||||
renderReference(q, gen, defn.getPieces(), v.getValueReference(), false);
|
||||
// } else if (v.hasValueAttachment()) {
|
||||
// renderAttachment(gen, defn.getPieces(), v.getValueAttachment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -759,8 +771,14 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (first) first = false; else vi.tx(", ");
|
||||
if (v.getValue().isPrimitive()) {
|
||||
vi.tx(v.getValue().primitiveValue());
|
||||
} else {
|
||||
} else if (v.hasValueCoding()) {
|
||||
renderCoding(vi, v.getValueCoding(), true);
|
||||
} else if (v.hasValueReference()) {
|
||||
renderReference(vi, v.getValueReference());
|
||||
} else if (v.hasValueQuantity()) {
|
||||
renderQuantity(vi, v.getValueQuantity());
|
||||
// } else if (v.hasValueAttachment()) {
|
||||
// renderAttachment(vi, v.getValueAttachment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,10 @@ import org.hl7.fhir.r5.utils.EOperationOutcome;
|
|||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
|
||||
|
||||
public abstract class ResourceRenderer extends DataRenderer {
|
||||
|
||||
|
@ -216,6 +218,82 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
public void renderReference(ResourceWrapper rw, XhtmlNode x, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
renderReference(rw, x, r, true);
|
||||
}
|
||||
|
||||
public void renderReference(Resource res, HierarchicalTableGenerator gen, List<Piece> pieces, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
if (r == null) {
|
||||
pieces.add(gen.new Piece(null, "null!", null));
|
||||
return;
|
||||
}
|
||||
ResourceWrapper rw = new ResourceWrapperDirect(this.context, res);
|
||||
ResourceWithReference tr = null;
|
||||
String link = null;
|
||||
StringBuilder text = new StringBuilder();
|
||||
if (r.hasReferenceElement() && allowLinks) {
|
||||
tr = resolveReference(rw, r.getReference());
|
||||
|
||||
if (!r.getReference().startsWith("#")) {
|
||||
if (tr != null && tr.getReference() != null) {
|
||||
link = tr.getReference();
|
||||
} else if (r.getReference().contains("?")) {
|
||||
text.append("Conditional Reference: ");
|
||||
} else {
|
||||
link = r.getReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tr != null && tr.getReference() != null && tr.getReference().startsWith("#")) {
|
||||
text.append("See above (");
|
||||
}
|
||||
// what to display: if text is provided, then that. if the reference was resolved, then show the name, or the generated narrative
|
||||
String display = r.hasDisplayElement() ? r.getDisplay() : null;
|
||||
String name = tr != null && tr.getResource() != null ? tr.getResource().getNameFromResource() : null;
|
||||
|
||||
if (display == null && (tr == null || tr.getResource() == null)) {
|
||||
if (!Utilities.noString(r.getReference())) {
|
||||
text.append(r.getReference());
|
||||
} else if (r.hasIdentifier()) {
|
||||
text.append(displayIdentifier(r.getIdentifier()));
|
||||
} else {
|
||||
text.append("??");
|
||||
}
|
||||
} else if (context.isTechnicalMode()) {
|
||||
text.append(r.getReference());
|
||||
if (display != null) {
|
||||
text.append(": "+display);
|
||||
}
|
||||
if ((tr == null || (tr.getReference() != null && !tr.getReference().startsWith("#"))) && name != null) {
|
||||
text.append(" \""+name+"\"");
|
||||
}
|
||||
if (r.hasExtension(ToolingExtensions.EXT_TARGET_ID) || r.hasExtension(ToolingExtensions.EXT_TARGET_PATH)) {
|
||||
text.append("(");
|
||||
for (Extension ex : r.getExtensionsByUrl(ToolingExtensions.EXT_TARGET_ID)) {
|
||||
if (ex.hasValue()) {
|
||||
text.append(", ");
|
||||
text.append("#"+ex.getValue().primitiveValue());
|
||||
}
|
||||
}
|
||||
for (Extension ex : r.getExtensionsByUrl(ToolingExtensions.EXT_TARGET_PATH)) {
|
||||
if (ex.hasValue()) {
|
||||
text.append(", ");
|
||||
text.append("/#"+ex.getValue().primitiveValue());
|
||||
}
|
||||
}
|
||||
text.append(")");
|
||||
}
|
||||
} else {
|
||||
if (display != null) {
|
||||
text.append(display);
|
||||
} else if (name != null) {
|
||||
text.append(name);
|
||||
} else {
|
||||
text.append(". Description: (todo)");
|
||||
}
|
||||
}
|
||||
if (tr != null && tr.getReference() != null && tr.getReference().startsWith("#")) {
|
||||
text.append(")");
|
||||
}
|
||||
pieces.add(gen.new Piece(link,text.toString(), null));
|
||||
}
|
||||
|
||||
public void renderReference(ResourceWrapper rw, XhtmlNode x, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
if (r == null) {
|
||||
|
|
|
@ -172,6 +172,7 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
protected boolean warnOnDraftOrExperimental;
|
||||
protected Set<String> statusWarnings = new HashSet<>();
|
||||
protected BestPracticeWarningLevel bpWarnings = BestPracticeWarningLevel.Warning;
|
||||
protected String sessionId = Utilities.makeUuidLC();
|
||||
|
||||
|
||||
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager, boolean debug) {
|
||||
|
@ -1083,8 +1084,8 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
String tt = extractResourceType(ref);
|
||||
ok = VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(tt);
|
||||
}
|
||||
if (!ok && stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
if (!ok && stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
hintOrError(!isWarning, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, ref, name);
|
||||
}
|
||||
return null;
|
||||
|
@ -1092,17 +1093,17 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
if (fragment != null) {
|
||||
int i = countFragmentMatches(el.get(0), fragment);
|
||||
if (i == 0) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
hintOrError(isNLLink, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_FRAGMENT, ref, fragment, name);
|
||||
} else if (i > 1) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE_FRAGMENT, i, ref, fragment, name);
|
||||
}
|
||||
}
|
||||
return el.get(0);
|
||||
} else {
|
||||
if (stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE, el.size(), ref, name);
|
||||
}
|
||||
return null;
|
||||
|
@ -1118,8 +1119,8 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
if (el.size() == 1) {
|
||||
return el.get(0);
|
||||
} else {
|
||||
if (stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE, el.size(), ref, name);
|
||||
}
|
||||
return null;
|
||||
|
@ -1140,17 +1141,17 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
if (!VersionUtilities.isR4Plus(context.getVersion())) {
|
||||
if (el.size() == 1) {
|
||||
return el.get(0);
|
||||
} else if (stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
} else if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
rulePlural(errors, "2023-11-15", IssueType.INVALID, stack, false, el.size(), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_APPARENT, ref, name, CommaSeparatedStringBuilder.join(",", Utilities.sorted(tl)));
|
||||
}
|
||||
} else if (stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
} else if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
rulePlural(errors, "2023-11-15", IssueType.INVALID, stack, false, el.size(), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_APPARENT, ref, name, CommaSeparatedStringBuilder.join(",", Utilities.sorted(tl)));
|
||||
}
|
||||
} else {
|
||||
if (stack != null && !source.hasUserData("bundle.error.noted")) {
|
||||
source.setUserData("bundle.error.noted", true);
|
||||
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
|
||||
source.setUserData("bundle.error.noted", sessionId);
|
||||
hintOrError(!isWarning, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, ref, name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4311,7 +4311,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
StructureDefinition sdt = context.fetchTypeDefinition(type);
|
||||
StructureDefinition tt = sdt;
|
||||
while (tt != null) {
|
||||
if (tt.getBaseDefinition().equals(sd.getUrl())) {
|
||||
if (sd.getUrl().equals(tt.getBaseDefinition())) {
|
||||
return sdt;
|
||||
}
|
||||
tt = context.fetchResource(StructureDefinition.class, tt.getBaseDefinition());
|
||||
|
|
|
@ -75,6 +75,8 @@ public class BundleValidator extends BaseValidator {
|
|||
|
||||
public boolean validateBundle(List<ValidationMessage> errors, Element bundle, NodeStack stack, boolean checkSpecials, ValidationContext hostContext, PercentageTracker pct, ValidationMode mode) {
|
||||
boolean ok = true;
|
||||
sessionId = Utilities.makeUuidLC();
|
||||
|
||||
String type = bundle.getNamedChildValue(TYPE, false);
|
||||
type = StringUtils.defaultString(type);
|
||||
List<Element> entries = new ArrayList<Element>();
|
||||
|
|
|
@ -574,7 +574,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
fpe.checkOnTypes(vc, rootPath, types, fpe.parse(exp), warnings);
|
||||
} else {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(rootPath);
|
||||
if (sd != null) {
|
||||
if (sd != null && sd.getKind() == StructureDefinitionKind.RESOURCE) {
|
||||
fpe.checkOnTypes(vc, rootPath, types, fpe.parse(exp), warnings);
|
||||
} else {
|
||||
fpe.checkOnTypes(vc, "DomainResource", types, fpe.parse(exp), warnings);
|
||||
|
|
Loading…
Reference in New Issue