commit
a5305277f3
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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#");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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://")) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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?
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue