Merge pull request #975 from hapifhir/gg-202211-fixes

Gg 202211 fixes
This commit is contained in:
Grahame Grieve 2022-11-02 22:06:09 +11:00 committed by GitHub
commit a5305277f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 139 additions and 29 deletions

View File

@ -1238,5 +1238,18 @@ public class Element extends Base {
} }
return "e:"+e+",w:"+w+",h:"+h; return "e:"+e+",w:"+w+",h:"+h;
} }
public void populatePaths(String path) {
if (path == null) {
path = fhirType();
}
setPath(path);
if (children != null) {
for (Element n : children) {
n.populatePaths(path+"."+n.getName());
}
}
}
} }

View File

@ -636,6 +636,10 @@ public class JsonParser extends ParserBase {
@Override @Override
public void compose(Element e, OutputStream stream, OutputStyle style, String identity) throws FHIRException, IOException { public void compose(Element e, OutputStream stream, OutputStyle style, String identity) throws FHIRException, IOException {
if (e.getPath() == null) {
e.populatePaths(null);
}
OutputStreamWriter osw = new OutputStreamWriter(stream, "UTF-8"); OutputStreamWriter osw = new OutputStreamWriter(stream, "UTF-8");
if (style == OutputStyle.CANONICAL) if (style == OutputStyle.CANONICAL)
json = new JsonCreatorCanonical(osw); json = new JsonCreatorCanonical(osw);
@ -654,6 +658,10 @@ public class JsonParser extends ParserBase {
} }
public void compose(Element e, JsonCreator json) throws Exception { public void compose(Element e, JsonCreator json) throws Exception {
if (e.getPath() == null) {
e.populatePaths(null);
}
this.json = json; this.json = json;
json.beginObject(); json.beginObject();

View File

@ -315,6 +315,10 @@ public class TurtleParser extends ParserBase {
public void compose(Element e, Turtle ttl, String base) throws FHIRException { public void compose(Element e, Turtle ttl, String base) throws FHIRException {
if (e.getPath() == null) {
e.populatePaths(null);
}
ttl.prefix("fhir", FHIR_URI_BASE); ttl.prefix("fhir", FHIR_URI_BASE);
ttl.prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); ttl.prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
ttl.prefix("owl", "http://www.w3.org/2002/07/owl#"); ttl.prefix("owl", "http://www.w3.org/2002/07/owl#");

View File

@ -602,6 +602,9 @@ public class XmlParser extends ParserBase {
xml.setSortAttributes(false); xml.setSortAttributes(false);
xml.setPretty(style == OutputStyle.PRETTY); xml.setPretty(style == OutputStyle.PRETTY);
xml.start(); xml.start();
if (e.getPath() == null) {
e.populatePaths(null);
}
String ns = e.getProperty().getXmlNamespace(); String ns = e.getProperty().getXmlNamespace();
if (ns!=null && !"noNamespace".equals(ns)) { if (ns!=null && !"noNamespace".equals(ns)) {
xml.setDefaultNamespace(ns); xml.setDefaultNamespace(ns);
@ -654,6 +657,9 @@ public class XmlParser extends ParserBase {
} }
public void compose(Element e, IXMLWriter xml) throws Exception { public void compose(Element e, IXMLWriter xml) throws Exception {
if (e.getPath() == null) {
e.populatePaths(null);
}
xml.start(); xml.start();
xml.setDefaultNamespace(e.getProperty().getXmlNamespace()); xml.setDefaultNamespace(e.getProperty().getXmlNamespace());
if (schemaPath != null) { if (schemaPath != null) {

View File

@ -15,6 +15,7 @@ import java.time.format.FormatStyle;
import java.time.format.SignStyle; import java.time.format.SignStyle;
import java.util.Currency; import java.util.Currency;
import java.util.List; import java.util.List;
import java.util.Set;
import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
@ -97,6 +98,45 @@ public class DataRenderer extends Renderer {
// -- 2. Markdown support ------------------------------------------------------- // -- 2. Markdown support -------------------------------------------------------
public static String processRelativeUrls(String markdown, String path) {
if (markdown == null) {
return "";
}
if (!Utilities.isAbsoluteUrl(path)) {
return markdown;
}
String basePath = path.contains("/") ? path.substring(0, path.lastIndexOf("/")+1) : path+"/";
StringBuilder b = new StringBuilder();
int i = 0;
while (i < markdown.length()) {
if (i < markdown.length()-3 && markdown.substring(i, i+2).equals("](")) {
int j = i + 2;
while (j < markdown.length() && markdown.charAt(j) != ')')
j++;
if (j < markdown.length()) {
String url = markdown.substring(i+2, j);
if (!Utilities.isAbsoluteUrl(url) && !url.startsWith("..")) {
// it's relative - so it's relative to the base URL
b.append("](");
b.append(basePath);
} else {
b.append("](");
}
i = i + 1;
} else
b.append(markdown.charAt(i));
} else {
b.append(markdown.charAt(i));
}
i++;
}
return b.toString();
}
protected void addMarkdown(XhtmlNode x, String text, String path) throws FHIRFormatError, IOException, DefinitionException {
addMarkdown(x, processRelativeUrls(text, path));
}
protected void addMarkdown(XhtmlNode x, String text) throws FHIRFormatError, IOException, DefinitionException { protected void addMarkdown(XhtmlNode x, String text) throws FHIRFormatError, IOException, DefinitionException {
if (text != null) { if (text != null) {
// 1. custom FHIR extensions // 1. custom FHIR extensions

View File

@ -68,6 +68,7 @@ import org.hl7.fhir.r5.renderers.utils.DirectWrappers;
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.BaseWrapperDirect; import org.hl7.fhir.r5.renderers.utils.DirectWrappers.BaseWrapperDirect;
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.PropertyWrapperDirect; import org.hl7.fhir.r5.renderers.utils.DirectWrappers.PropertyWrapperDirect;
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect; import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference; import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
@ -103,7 +104,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
boolean idDone = false; boolean idDone = false;
XhtmlNode p = x.para(); XhtmlNode p = x.para();
if (context.isAddGeneratedNarrativeHeader()) { if (context.isAddGeneratedNarrativeHeader()) {
p.b().tx("Generated Narrative: "+r.fhirType()); p.b().tx("Generated Narrative: "+r.fhirType()+(context.isContained() ? " #"+r.getId() : ""));
if (!Utilities.noString(r.getId())) { if (!Utilities.noString(r.getId())) {
p.an(r.getId()); p.an(r.getId());
} }
@ -756,35 +757,50 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
if (children.isEmpty()) { if (children.isEmpty()) {
renderLeaf(res, e, defn, x, x, false, showCodeDetails, readDisplayHints(defn), path, indent); renderLeaf(res, e, defn, x, x, false, showCodeDetails, readDisplayHints(defn), path, indent);
} else { } else {
for (PropertyWrapper p : splitExtensions(profile, e.children())) { List<PropertyWrapper> pl = splitExtensions(profile, e.children());
if (p.hasValues()) { for (PropertyWrapper p : pl) {
ElementDefinition child = getElementDefinition(children, path+"."+p.getName(), p); generateForProperty(res, profile, allElements, children, x, path, showCodeDetails, indent, false, p);
if (child == null) { }
child = p.getElementDefinition(); for (PropertyWrapper p : pl) {
} generateForProperty(res, profile, allElements, children, x, path, showCodeDetails, indent, true, p);
if (child != null) { }
if (!child.getBase().hasPath() || !child.getBase().getPath().startsWith("Resource.")) { }
generateElementByProfile(res, profile, allElements, x, path, showCodeDetails, indent, p, child); }
}
} private void generateForProperty(ResourceWrapper res, StructureDefinition profile,
List<ElementDefinition> allElements, List<ElementDefinition> children, XhtmlNode x, String path,
boolean showCodeDetails, int indent, boolean round2, PropertyWrapper p)
throws UnsupportedEncodingException, IOException, EOperationOutcome {
if (p.hasValues()) {
ElementDefinition child = getElementDefinition(children, path+"."+p.getName(), p);
if (child == null) {
child = p.getElementDefinition();
}
if (child != null) {
if (!child.getBase().hasPath() || !child.getBase().getPath().startsWith("Resource.")) {
generateElementByProfile(res, profile, allElements, x, path, showCodeDetails, indent, p, child, round2);
} }
} }
} }
} }
public void generateElementByProfile(ResourceWrapper res, StructureDefinition profile, List<ElementDefinition> allElements, XhtmlNode x, String path, public void generateElementByProfile(ResourceWrapper res, StructureDefinition profile, List<ElementDefinition> allElements, XhtmlNode x, String path,
boolean showCodeDetails, int indent, PropertyWrapper p, ElementDefinition child) throws UnsupportedEncodingException, IOException, EOperationOutcome { boolean showCodeDetails, int indent, PropertyWrapper p, ElementDefinition child, boolean round2) throws UnsupportedEncodingException, IOException, EOperationOutcome {
Map<String, String> displayHints = readDisplayHints(child); Map<String, String> displayHints = readDisplayHints(child);
if ("DomainResource.contained".equals(child.getBase().getPath())) { if ("DomainResource.contained".equals(child.getBase().getPath())) {
// for (BaseWrapper v : p.getValues()) { if (round2) {
// x.hr(); for (BaseWrapper v : p.getValues()) {
// RenderingContext ctxt = context.clone(); if (!RendererFactory.hasSpecificRenderer(v.fhirType())) {
// ctxt.setContained(true); x.hr();
// ResourceRenderer rnd = RendererFactory.factory(v.fhirType(), ctxt); RenderingContext ctxt = context.copy();
// ResourceWrapper rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase()); ctxt.setContained(true);
// rnd.render(x.blockquote(), rw); ResourceRenderer rnd = RendererFactory.factory(v.fhirType(), ctxt);
// } ResourceWrapper rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase());
} else if (!exemptFromRendering(child)) { rnd.render(x.blockquote(), rw);
}
}
}
} else if (!round2 && !exemptFromRendering(child)) {
if (isExtension(p)) { if (isExtension(p)) {
hasExtensions = true; hasExtensions = true;
} }

View File

@ -769,7 +769,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
td = tr.td(); td = tr.td();
if (cs != null) { if (cs != null) {
String defn = CodeSystemUtilities.getCodeDefinition(cs, c.getCode()); String defn = CodeSystemUtilities.getCodeDefinition(cs, c.getCode());
addMarkdown(td, defn); addMarkdown(td, defn, cs.getUserString("path"));
} }
} }
for (String n : Utilities.sorted(properties.keySet())) { for (String n : Utilities.sorted(properties.keySet())) {

View File

@ -139,7 +139,9 @@ public class SimpleHTTPClient {
u = new URL(url); u = new URL(url);
c = (HttpURLConnection) u.openConnection(); c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET"); c.setRequestMethod("GET");
c.setRequestProperty("Accept", accept); if (accept != null) {
c.setRequestProperty("Accept", accept);
}
setHeaders(c); setHeaders(c);
c.setInstanceFollowRedirects(false); c.setInstanceFollowRedirects(false);
if (trustAll && url.startsWith("https://")) { if (trustAll && url.startsWith("https://")) {

View File

@ -618,6 +618,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
if (map == null) throw new Error("Unable to find map " + mapUri + " (Known Maps = " + context.listMapUrls() + ")"); if (map == null) throw new Error("Unable to find map " + mapUri + " (Known Maps = " + context.listMapUrls() + ")");
org.hl7.fhir.r5.elementmodel.Element resource = getTargetResourceFromStructureMap(map); org.hl7.fhir.r5.elementmodel.Element resource = getTargetResourceFromStructureMap(map);
scu.transform(null, src, map, resource); scu.transform(null, src, map, resource);
resource.populatePaths(null);
return resource; return resource;
} }

View File

@ -385,6 +385,7 @@ public class ValidationService {
for (String src : cliContext.getIgs()) { for (String src : cliContext.getIgs()) {
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), src, cliContext.isRecursive()); igLoader.loadIg(validator.getIgs(), validator.getBinaries(), src, cliContext.isRecursive());
} }
System.out.println(" Package Summary: "+validator.getContext().loadedPackageSummary());
System.out.print(" Get set... "); System.out.print(" Get set... ");
validator.setQuestionnaireMode(cliContext.getQuestionnaireMode()); validator.setQuestionnaireMode(cliContext.getQuestionnaireMode());
validator.setLevel(cliContext.getLevel()); validator.setLevel(cliContext.getLevel());

View File

@ -2410,12 +2410,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
DecimalStatus ds = Utilities.checkDecimal(e.primitiveValue(), true, false); DecimalStatus ds = Utilities.checkDecimal(e.primitiveValue(), true, false);
if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, ds == DecimalStatus.OK || ds == DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_VALID, e.primitiveValue())) { if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, ds == DecimalStatus.OK || ds == DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_VALID, e.primitiveValue())) {
warning(errors, IssueType.VALUE, e.line(), e.col(), path, ds != DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_RANGE, e.primitiveValue()); warning(errors, IssueType.VALUE, e.line(), e.col(), path, ds != DecimalStatus.RANGE, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_RANGE, e.primitiveValue());
try { try {
Decimal v = new Decimal(e.getValue()); Decimal v = new Decimal(e.getValue());
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMaxValueDecimalType() || if (context.hasMaxValueDecimalType() && context.getMaxValueDecimalType().hasValue()) {
!context.getMaxValueDecimalType().hasValue() || checkDecimalMaxValue(v, context.getMaxValueDecimalType().getValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_GT, (context.hasMaxValueDecimalType() ? context.getMaxValueDecimalType() : "")) && ok; ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, checkDecimalMaxValue(v, context.getMaxValueDecimalType().getValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_GT, context.getMaxValueDecimalType()) && ok;
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMinValueIntegerType() || } else if (context.hasMaxValueIntegerType() && context.getMaxValueIntegerType().hasValue()) {
!context.getMinValueIntegerType().hasValue() || checkDecimalMinValue(v, context.getMaxValueDecimalType().getValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_LT, (context.hasMinValueIntegerType() ? context.getMinValueIntegerType() : "")) && ok; // users can also provide a max integer type. It's not clear whether that's actually valid, but we'll check for it anyway
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, checkDecimalMaxValue(v, new BigDecimal(context.getMaxValueIntegerType().getValue())), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_GT, context.getMaxValueIntegerType()) && ok;
}
if (context.hasMinValueDecimalType() && context.getMaxValueDecimalType().hasValue()) {
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, checkDecimalMinValue(v, context.getMaxValueDecimalType().getValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_LT, context.getMaxValueDecimalType()) && ok;
} else if (context.hasMinValueIntegerType() && context.getMaxValueIntegerType().hasValue()) {
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, checkDecimalMinValue(v, new BigDecimal(context.getMaxValueIntegerType().getValue())), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_LT, context.getMaxValueIntegerType()) && ok;
}
} catch (Exception ex) { } catch (Exception ex) {
// should never happen? // should never happen?
} }

View File

@ -2067,3 +2067,14 @@ v: {
"system" : "http://snomed.info/sct" "system" : "http://snomed.info/sct"
} }
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "324689003",
"display" : "Nystatin 100000 unit/mL oral suspension"
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
v: {
"display" : "Product containing precisely nystatin 100000 unit/1 milliliter conventional release oral suspension (clinical drug)",
"code" : "324689003",
"system" : "http://snomed.info/sct"
}
-------------------------------------------------------------------------------------