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;
}
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
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");
if (style == OutputStyle.CANONICAL)
json = new JsonCreatorCanonical(osw);
@ -654,6 +658,10 @@ public class JsonParser extends ParserBase {
}
public void compose(Element e, JsonCreator json) throws Exception {
if (e.getPath() == null) {
e.populatePaths(null);
}
this.json = json;
json.beginObject();

View File

@ -315,6 +315,10 @@ public class TurtleParser extends ParserBase {
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("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
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.setPretty(style == OutputStyle.PRETTY);
xml.start();
if (e.getPath() == null) {
e.populatePaths(null);
}
String ns = e.getProperty().getXmlNamespace();
if (ns!=null && !"noNamespace".equals(ns)) {
xml.setDefaultNamespace(ns);
@ -654,6 +657,9 @@ public class XmlParser extends ParserBase {
}
public void compose(Element e, IXMLWriter xml) throws Exception {
if (e.getPath() == null) {
e.populatePaths(null);
}
xml.start();
xml.setDefaultNamespace(e.getProperty().getXmlNamespace());
if (schemaPath != null) {

View File

@ -15,6 +15,7 @@ import java.time.format.FormatStyle;
import java.time.format.SignStyle;
import java.util.Currency;
import java.util.List;
import java.util.Set;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
@ -97,6 +98,45 @@ public class DataRenderer extends Renderer {
// -- 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 {
if (text != null) {
// 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.PropertyWrapperDirect;
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.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
@ -103,7 +104,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
boolean idDone = false;
XhtmlNode p = x.para();
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())) {
p.an(r.getId());
}
@ -756,35 +757,50 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
if (children.isEmpty()) {
renderLeaf(res, e, defn, x, x, false, showCodeDetails, readDisplayHints(defn), path, indent);
} else {
for (PropertyWrapper p : splitExtensions(profile, e.children())) {
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);
}
}
List<PropertyWrapper> pl = splitExtensions(profile, e.children());
for (PropertyWrapper p : pl) {
generateForProperty(res, profile, allElements, children, x, path, showCodeDetails, indent, false, p);
}
for (PropertyWrapper p : pl) {
generateForProperty(res, profile, allElements, children, x, path, showCodeDetails, indent, true, p);
}
}
}
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,
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);
if ("DomainResource.contained".equals(child.getBase().getPath())) {
// for (BaseWrapper v : p.getValues()) {
// x.hr();
// RenderingContext ctxt = context.clone();
// ctxt.setContained(true);
// ResourceRenderer rnd = RendererFactory.factory(v.fhirType(), ctxt);
// ResourceWrapper rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase());
// rnd.render(x.blockquote(), rw);
// }
} else if (!exemptFromRendering(child)) {
if (round2) {
for (BaseWrapper v : p.getValues()) {
if (!RendererFactory.hasSpecificRenderer(v.fhirType())) {
x.hr();
RenderingContext ctxt = context.copy();
ctxt.setContained(true);
ResourceRenderer rnd = RendererFactory.factory(v.fhirType(), ctxt);
ResourceWrapper rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase());
rnd.render(x.blockquote(), rw);
}
}
}
} else if (!round2 && !exemptFromRendering(child)) {
if (isExtension(p)) {
hasExtensions = true;
}

View File

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

View File

@ -139,7 +139,9 @@ public class SimpleHTTPClient {
u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Accept", accept);
if (accept != null) {
c.setRequestProperty("Accept", accept);
}
setHeaders(c);
c.setInstanceFollowRedirects(false);
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() + ")");
org.hl7.fhir.r5.elementmodel.Element resource = getTargetResourceFromStructureMap(map);
scu.transform(null, src, map, resource);
resource.populatePaths(null);
return resource;
}

View File

@ -385,6 +385,7 @@ public class ValidationService {
for (String src : cliContext.getIgs()) {
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), src, cliContext.isRecursive());
}
System.out.println(" Package Summary: "+validator.getContext().loadedPackageSummary());
System.out.print(" Get set... ");
validator.setQuestionnaireMode(cliContext.getQuestionnaireMode());
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);
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());
try {
try {
Decimal v = new Decimal(e.getValue());
ok = rule(errors, IssueType.INVALID, e.line(), e.col(), path, !context.hasMaxValueDecimalType() ||
!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, !context.hasMinValueIntegerType() ||
!context.getMinValueIntegerType().hasValue() || checkDecimalMinValue(v, context.getMaxValueDecimalType().getValue()), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_DECIMAL_LT, (context.hasMinValueIntegerType() ? context.getMinValueIntegerType() : "")) && ok;
if (context.hasMaxValueDecimalType() && context.getMaxValueDecimalType().hasValue()) {
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;
} else if (context.hasMaxValueIntegerType() && context.getMaxValueIntegerType().hasValue()) {
// 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) {
// should never happen?
}

View File

@ -2067,3 +2067,14 @@ v: {
"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"
}
-------------------------------------------------------------------------------------