migrate r5 changes to r4b
This commit is contained in:
parent
e2d1cbfffa
commit
1aab88f6a7
|
@ -624,6 +624,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
throw new DefinitionException(context.formatMessage(I18nConstants.BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___, base.getUrl(), base.getType(), derived.getUrl(), derived.getType()));
|
||||
}
|
||||
|
||||
fixTypeOfResourceId(base);
|
||||
|
||||
if (snapshotStack.contains(derived.getUrl())) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__, snapshotStack.toString()));
|
||||
}
|
||||
|
@ -803,6 +805,25 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
private void fixTypeOfResourceId(StructureDefinition base) {
|
||||
if (base.getKind() == StructureDefinitionKind.RESOURCE && (base.getFhirVersion() == null || VersionUtilities.isR4Plus(base.getFhirVersion().toCode()))) {
|
||||
fixTypeOfResourceId(base.getSnapshot().getElement());
|
||||
fixTypeOfResourceId(base.getDifferential().getElement());
|
||||
}
|
||||
}
|
||||
|
||||
private void fixTypeOfResourceId(List<ElementDefinition> list) {
|
||||
for (ElementDefinition ed : list) {
|
||||
if (ed.hasBase() && ed.getBase().getPath().equals("Resource.id")) {
|
||||
for (TypeRefComponent tr : ed.getType()) {
|
||||
tr.setCode("http://hl7.org/fhirpath/System.String");
|
||||
tr.removeExtension(ToolingExtensions.EXT_FHIR_TYPE);
|
||||
ToolingExtensions.addUrlExtension(tr, ToolingExtensions.EXT_FHIR_TYPE, "id");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
||||
if (derived.hasDifferential() && !derived.getDifferential().getElementFirstRep().getPath().contains(".") && !derived.getDifferential().getElementFirstRep().getType().isEmpty()) {
|
||||
if (wantFixDifferentialFirstElementType && typeMatchesAncestor(derived.getDifferential().getElementFirstRep().getType(), derived.getBaseDefinition())) {
|
||||
|
@ -3740,7 +3761,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
} else if (Utilities.isAbsoluteUrl(u)) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u);
|
||||
if (sd != null) {
|
||||
if (sd != null && pkp != null) {
|
||||
String disp = sd.hasTitle() ? sd.getTitle() : sd.getName();
|
||||
String ref = pkp.getLinkForProfile(null, sd.getUrl());
|
||||
if (ref != null && ref.contains("|"))
|
||||
|
@ -4214,6 +4235,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
Row currRow = row;
|
||||
List<ElementChoiceGroup> groups = readChoices(element, children);
|
||||
boolean isExtension = Utilities.existsInList(tail(element.getPath()), "extension", "modifierExtension");
|
||||
if (!element.prohibited()) {
|
||||
for (ElementDefinition child : children) {
|
||||
if (!child.hasSliceName()) {
|
||||
currRow = row;
|
||||
|
@ -4224,6 +4246,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (!snapshot && (extensions == null || !extensions))
|
||||
// for (ElementDefinition child : children)
|
||||
// if (child.getPath().endsWith(".extension") || child.getPath().endsWith(".modifierExtension"))
|
||||
|
@ -4334,7 +4357,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc));
|
||||
} else {
|
||||
String name = urltail(eurl);
|
||||
String name = element.hasSliceName() ? element.getSliceName() : urltail(eurl);
|
||||
nameCell.getPieces().get(0).setText(name);
|
||||
// left.getPieces().get(0).setReference((String) extDefn.getExtensionStructure().getTag("filename"));
|
||||
nameCell.getPieces().get(0).setHint(translate("sd.table", "Extension URL")+" = "+extDefn.getUrl());
|
||||
|
|
|
@ -11464,6 +11464,26 @@ When pattern[x] is used to constrain a complex object, it means that each proper
|
|||
return getType().size() == 1 && Utilities.existsInList(getType().get(0).getCode(), "Element", "BackboneElement");
|
||||
}
|
||||
|
||||
public boolean prohibited() {
|
||||
return "0".equals(getMax());
|
||||
}
|
||||
|
||||
public boolean hasFixedOrPattern() {
|
||||
return hasFixed() || hasPattern();
|
||||
}
|
||||
|
||||
public DataType getFixedOrPattern() {
|
||||
return hasFixed() ? getFixed() : getPattern();
|
||||
}
|
||||
|
||||
public boolean isProhibited() {
|
||||
return "0".equals(getMax());
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return getMin() == 1;
|
||||
}
|
||||
|
||||
|
||||
// end addition
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package org.hl7.fhir.r4b.renderers;
|
||||
|
||||
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
|
||||
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
|
||||
import static java.time.temporal.ChronoField.YEAR;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
|
@ -9,8 +13,12 @@ import java.text.SimpleDateFormat;
|
|||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.chrono.IsoChronology;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.time.format.ResolverStyle;
|
||||
import java.time.format.SignStyle;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
@ -22,6 +30,7 @@ import org.hl7.fhir.r4b.context.IWorkerContext;
|
|||
import org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r4b.model.Address;
|
||||
import org.hl7.fhir.r4b.model.Annotation;
|
||||
import org.hl7.fhir.r4b.model.BackboneType;
|
||||
import org.hl7.fhir.r4b.model.Base;
|
||||
import org.hl7.fhir.r4b.model.BaseDateTimeType;
|
||||
import org.hl7.fhir.r4b.model.CanonicalResource;
|
||||
|
@ -39,6 +48,8 @@ import org.hl7.fhir.r4b.model.DataRequirement.SortDirection;
|
|||
import org.hl7.fhir.r4b.model.ContactPoint.ContactPointSystem;
|
||||
import org.hl7.fhir.r4b.model.DataType;
|
||||
import org.hl7.fhir.r4b.model.DateTimeType;
|
||||
import org.hl7.fhir.r4b.model.DateType;
|
||||
import org.hl7.fhir.r4b.model.ElementDefinition;
|
||||
import org.hl7.fhir.r4b.model.Enumeration;
|
||||
import org.hl7.fhir.r4b.model.Expression;
|
||||
import org.hl7.fhir.r4b.model.Extension;
|
||||
|
@ -69,6 +80,7 @@ import org.hl7.fhir.r4b.renderers.utils.BaseWrappers.BaseWrapper;
|
|||
import org.hl7.fhir.r4b.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r4b.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||
import org.hl7.fhir.r4b.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r4b.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||
|
@ -348,8 +360,138 @@ public class DataRenderer extends Renderer {
|
|||
return value.primitiveValue();
|
||||
}
|
||||
|
||||
// -- 6. General purpose extension rendering ----------------------------------------------
|
||||
|
||||
// -- 5. Data type Rendering ----------------------------------------------
|
||||
public boolean hasRenderableExtensions(DataType element) {
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasRenderableExtensions(BackboneType element) {
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return element.hasModifierExtension();
|
||||
}
|
||||
|
||||
private String getExtensionLabel(Extension ext) {
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, ext.getUrl());
|
||||
if (sd != null && ext.getValue().isPrimitive() && sd.hasSnapshot()) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (Utilities.existsInList(ed.getPath(), "Extension", "Extension.value[x]") && ed.hasLabel()) {
|
||||
return ed.getLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean canRender(Extension ext) {
|
||||
return getExtensionLabel(ext) != null;
|
||||
}
|
||||
|
||||
public void renderExtensionsInList(XhtmlNode ul, DataType element) throws FHIRFormatError, DefinitionException, IOException {
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
String lbl = getExtensionLabel(ext);
|
||||
XhtmlNode li = ul.li();
|
||||
li.tx(lbl);
|
||||
li.tx(": ");
|
||||
render(li, ext.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renderExtensionsInList(XhtmlNode ul, BackboneType element) throws FHIRFormatError, DefinitionException, IOException {
|
||||
for (Extension ext : element.getModifierExtension()) {
|
||||
if (canRender(ext)) {
|
||||
String lbl = getExtensionLabel(ext);
|
||||
XhtmlNode li = ul.li();
|
||||
li = li.b();
|
||||
li.tx(lbl);
|
||||
li.tx(": ");
|
||||
render(li, ext.getValue());
|
||||
} else {
|
||||
// somehow have to do better than this
|
||||
XhtmlNode li = ul.li();
|
||||
li.b().tx("WARNING: Unrenderable Modifier Extension!");
|
||||
}
|
||||
}
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
String lbl = getExtensionLabel(ext);
|
||||
XhtmlNode li = ul.li();
|
||||
li.tx(lbl);
|
||||
li.tx(": ");
|
||||
render(li, ext.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renderExtensionsInText(XhtmlNode div, DataType element, String sep) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean first = true;
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
div.tx(sep);
|
||||
div.tx(" ");
|
||||
}
|
||||
|
||||
String lbl = getExtensionLabel(ext);
|
||||
div.tx(lbl);
|
||||
div.tx(": ");
|
||||
render(div, ext.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renderExtensionsInList(XhtmlNode div, BackboneType element, String sep) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean first = true;
|
||||
for (Extension ext : element.getModifierExtension()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
div.tx(sep);
|
||||
div.tx(" ");
|
||||
}
|
||||
if (canRender(ext)) {
|
||||
String lbl = getExtensionLabel(ext);
|
||||
XhtmlNode b = div.b();
|
||||
b.tx(lbl);
|
||||
b.tx(": ");
|
||||
render(div, ext.getValue());
|
||||
} else {
|
||||
// somehow have to do better than this
|
||||
div.b().tx("WARNING: Unrenderable Modifier Extension!");
|
||||
}
|
||||
}
|
||||
for (Extension ext : element.getExtension()) {
|
||||
if (canRender(ext)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
div.tx(sep);
|
||||
div.tx(" ");
|
||||
}
|
||||
|
||||
String lbl = getExtensionLabel(ext);
|
||||
div.tx(lbl);
|
||||
div.tx(": ");
|
||||
render(div, ext.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -- 6. Data type Rendering ----------------------------------------------
|
||||
|
||||
public static String display(IWorkerContext context, DataType type) {
|
||||
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.END_USER)).display(type);
|
||||
|
@ -413,15 +555,8 @@ public class DataRenderer extends Renderer {
|
|||
// mode - if rendering mode is technical, format defaults to XML format
|
||||
// locale - otherwise, format defaults to SHORT for the Locale (which defaults to default Locale)
|
||||
if (isOnlyDate(type.getPrecision())) {
|
||||
DateTimeFormatter fmt = context.getDateFormat();
|
||||
if (fmt == null) {
|
||||
if (context.isTechnicalMode()) {
|
||||
fmt = DateTimeFormatter.ISO_DATE;
|
||||
} else {
|
||||
fmt = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(context.getLocale());
|
||||
}
|
||||
}
|
||||
|
||||
DateTimeFormatter fmt = getDateFormatForPrecision(type);
|
||||
LocalDate date = LocalDate.of(type.getYear(), type.getMonth()+1, type.getDay());
|
||||
return fmt.format(date);
|
||||
}
|
||||
|
@ -442,6 +577,43 @@ public class DataRenderer extends Renderer {
|
|||
return fmt.format(zdt);
|
||||
}
|
||||
|
||||
private DateTimeFormatter getDateFormatForPrecision(BaseDateTimeType type) {
|
||||
DateTimeFormatter fmt = getContextDateFormat(type);
|
||||
if (fmt != null) {
|
||||
return fmt;
|
||||
}
|
||||
if (context.isTechnicalMode()) {
|
||||
switch (type.getPrecision()) {
|
||||
case YEAR:
|
||||
return new DateTimeFormatterBuilder().appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD).toFormatter();
|
||||
case MONTH:
|
||||
return new DateTimeFormatterBuilder().appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD).appendLiteral('-').appendValue(MONTH_OF_YEAR, 2).toFormatter();
|
||||
default:
|
||||
return DateTimeFormatter.ISO_DATE;
|
||||
}
|
||||
} else {
|
||||
switch (type.getPrecision()) {
|
||||
case YEAR:
|
||||
return DateTimeFormatter.ofPattern("uuuu");
|
||||
case MONTH:
|
||||
return DateTimeFormatter.ofPattern("MMM uuuu");
|
||||
default:
|
||||
return DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(context.getLocale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DateTimeFormatter getContextDateFormat(BaseDateTimeType type) {
|
||||
switch (type.getPrecision()) {
|
||||
case YEAR:
|
||||
return context.getDateYearFormat();
|
||||
case MONTH:
|
||||
return context.getDateYearMonthFormat();
|
||||
default:
|
||||
return context.getDateFormat();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOnlyDate(TemporalPrecisionEnum temporalPrecisionEnum) {
|
||||
return temporalPrecisionEnum == TemporalPrecisionEnum.YEAR || temporalPrecisionEnum == TemporalPrecisionEnum.MONTH || temporalPrecisionEnum == TemporalPrecisionEnum.DAY;
|
||||
}
|
||||
|
@ -533,6 +705,12 @@ public class DataRenderer extends Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void renderDate(XhtmlNode x, Base e) {
|
||||
if (e.hasPrimitiveValue()) {
|
||||
x.addText(displayDateTime((DateType) e));
|
||||
}
|
||||
}
|
||||
|
||||
public void renderDateTime(XhtmlNode x, String s) {
|
||||
if (s != null) {
|
||||
DateTimeType dt = new DateTimeType(s);
|
||||
|
@ -739,7 +917,7 @@ public class DataRenderer extends Renderer {
|
|||
CodeSystem cs = context.getWorker().fetchCodeSystem(system, version);
|
||||
if (cs != null && cs.hasUserData("path")) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return cs.getUserString("path")+"#"+Utilities.nmtokenize(code);
|
||||
return cs.getUserString("path")+"#"+cs.getId()+"-"+Utilities.nmtokenize(code);
|
||||
} else {
|
||||
return cs.getUserString("path");
|
||||
}
|
||||
|
@ -755,8 +933,9 @@ public class DataRenderer extends Renderer {
|
|||
if (Utilities.noString(s))
|
||||
s = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||
|
||||
CodeSystem cs = context.getWorker().fetchCodeSystem(c.getSystem());
|
||||
|
||||
String sn = describeSystem(c.getSystem());
|
||||
String sn = cs != null ? cs.present() : describeSystem(c.getSystem());
|
||||
String link = getLinkForCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||
if (link != null) {
|
||||
x.ah(link).tx(sn);
|
||||
|
@ -821,11 +1000,11 @@ public class DataRenderer extends Renderer {
|
|||
return s;
|
||||
}
|
||||
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) {
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) throws FHIRFormatError, DefinitionException, IOException {
|
||||
renderCodeableConcept(x, cc, false);
|
||||
}
|
||||
|
||||
protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) {
|
||||
protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (e.hasConcept()) {
|
||||
renderCodeableConcept(x, e.getConcept(), showCodeDetails);
|
||||
}
|
||||
|
@ -834,7 +1013,7 @@ public class DataRenderer extends Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) {
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (cc.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -890,6 +1069,12 @@ public class DataRenderer extends Renderer {
|
|||
sp.tx(" \""+c.getDisplay()+"\"");
|
||||
}
|
||||
}
|
||||
if (hasRenderableExtensions(cc)) {
|
||||
if (!first) {
|
||||
sp.tx("; ");
|
||||
}
|
||||
renderExtensionsInText(sp, cc, ";");
|
||||
}
|
||||
sp.tx(")");
|
||||
} else {
|
||||
|
||||
|
@ -1139,9 +1324,11 @@ public class DataRenderer extends Renderer {
|
|||
protected String displayQuantity(Quantity q) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
s.append("(system = '").append(TerminologyRenderer.describeSystem(q.getSystem()))
|
||||
.append("' code ").append(q.getCode())
|
||||
.append(" = '").append(lookupCode(q.getSystem(), null, q.getCode())).append("')");
|
||||
s.append(q.hasValue() ? q.getValue() : "?");
|
||||
if (q.hasUnit())
|
||||
s.append(" ").append(q.getUnit());
|
||||
else if (q.hasCode())
|
||||
s.append(" ").append(q.getCode());
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
@ -1158,26 +1345,33 @@ public class DataRenderer extends Renderer {
|
|||
}
|
||||
if (q.hasUnit())
|
||||
x.tx(" "+q.getUnit());
|
||||
else if (q.hasCode())
|
||||
else if (q.hasCode() && q.hasSystem()) {
|
||||
// if there's a code there *shall* be a system, so if we've got one and not the other, things are invalid and we won't bother trying to render
|
||||
if (q.hasSystem() && q.getSystem().equals("http://unitsofmeasure.org"))
|
||||
x.tx(" "+q.getCode());
|
||||
else
|
||||
x.tx("(unit "+q.getCode()+" from "+q.getSystem()+")");
|
||||
}
|
||||
if (showCodeDetails && q.hasCode()) {
|
||||
x.span("background: LightGoldenRodYellow", null).tx(" (Details: "+TerminologyRenderer.describeSystem(q.getSystem())+" code "+q.getCode()+" = '"+lookupCode(q.getSystem(), null, q.getCode())+"')");
|
||||
}
|
||||
}
|
||||
|
||||
public String displayRange(Range q) {
|
||||
if (!q.hasLow() && !q.hasHigh())
|
||||
return "?";
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (q.hasLow())
|
||||
b.append(q.getLow().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
b.append("-");
|
||||
if (q.hasHigh())
|
||||
b.append(q.getHigh().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
if (q.getLow().hasUnit())
|
||||
b.append(" "+q.getLow().getUnit());
|
||||
|
||||
boolean sameUnits = (q.getLow().hasUnit() && q.getHigh().hasUnit() && q.getLow().getUnit().equals(q.getHigh().getUnit()))
|
||||
|| (q.getLow().hasCode() && q.getHigh().hasCode() && q.getLow().getCode().equals(q.getHigh().getCode()));
|
||||
String low = "?";
|
||||
if (q.hasLow() && q.getLow().hasValue())
|
||||
low = sameUnits ? q.getLow().getValue().toString() : displayQuantity(q.getLow());
|
||||
String high = displayQuantity(q.getHigh());
|
||||
if (high.isEmpty())
|
||||
high = "?";
|
||||
b.append(low).append("\u00A0to\u00A0").append(high);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,10 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
if (context.isAddGeneratedNarrativeHeader()) {
|
||||
x.para().b().tx("Generated Narrative: "+r.fhirType());
|
||||
}
|
||||
if (context.isTechnicalMode()) {
|
||||
if (!Utilities.noString(r.getId())) {
|
||||
x.an(r.getId());
|
||||
}
|
||||
if (context.isTechnicalMode() && !context.isContained()) {
|
||||
renderResourceHeader(r, x);
|
||||
}
|
||||
try {
|
||||
|
@ -312,9 +315,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
x.addText(new Base64().encodeAsString(((Base64BinaryType) e).getValue()));
|
||||
else if (e instanceof org.hl7.fhir.r4b.model.DateType) {
|
||||
org.hl7.fhir.r4b.model.DateType dt = ((org.hl7.fhir.r4b.model.DateType) e);
|
||||
if (((org.hl7.fhir.r4b.model.DateType) e).hasValue()) {
|
||||
x.addText(((org.hl7.fhir.r4b.model.DateType) e).toHumanDisplay());
|
||||
}
|
||||
renderDate(x, dt);
|
||||
} else if (e instanceof Enumeration) {
|
||||
Object ev = ((Enumeration<?>) e).getValue();
|
||||
x.addText(ev == null ? "" : ev.toString()); // todo: look up a display name if there is one
|
||||
|
@ -397,9 +398,17 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
if (rw == null) {
|
||||
renderReference(res, x, r);
|
||||
} else {
|
||||
String ref = context.getResolver().urlForContained(context, res.fhirType(), res.getId(), rw.fhirType(), rw.getId());
|
||||
if (ref == null) {
|
||||
x.an(rw.getId());
|
||||
ResourceRenderer rr = RendererFactory.factory(rw, context.copy().setAddGeneratedNarrativeHeader(false));
|
||||
RenderingContext ctxtc = context.copy();
|
||||
ctxtc.setAddGeneratedNarrativeHeader(false);
|
||||
ctxtc.setContained(true);
|
||||
ResourceRenderer rr = RendererFactory.factory(rw, ctxtc);
|
||||
rr.render(parent.blockquote(), rw);
|
||||
} else {
|
||||
x.ah(ref).tx("See "+rw.fhirType());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -649,7 +658,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
private boolean generateByProfile(StructureDefinition profile, boolean showCodeDetails) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
if(context.isAddGeneratedNarrativeHeader()) {
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
x.para().b().tx("Generated Narrative: "+profile.present()+(showCodeDetails ? " with Details" : ""));
|
||||
}
|
||||
try {
|
||||
generateByProfile(rcontext.getResourceResource(), profile, rcontext.getResourceResource(), profile.getSnapshot().getElement(), profile.getSnapshot().getElement().get(0), getChildrenForPath(profile.getSnapshot().getElement(), rcontext.getResourceResource().getResourceType().toString()), x, rcontext.getResourceResource().getResourceType().toString(), showCodeDetails);
|
||||
|
@ -689,10 +698,13 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
boolean showCodeDetails, int indent, PropertyWrapper p, ElementDefinition child) throws UnsupportedEncodingException, IOException, EOperationOutcome {
|
||||
Map<String, String> displayHints = readDisplayHints(child);
|
||||
if ("DomainResource.contained".equals(child.getBase().getPath())) {
|
||||
// if (p.getValues().size() > 0 && child != null) {
|
||||
// for (BaseWrapper v : p.getValues()) {
|
||||
// x.an(v.get("id").primitiveValue());
|
||||
// }
|
||||
// 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 (isExtension(p)) {
|
||||
|
|
|
@ -53,7 +53,10 @@ public class Renderer {
|
|||
protected static final String RENDER_BUNDLE_IF_MOD = "RENDER_BUNDLE_IF_MOD";
|
||||
protected static final String RENDER_BUNDLE_IF_MATCH = "RENDER_BUNDLE_IF_MATCH";
|
||||
protected static final String RENDER_BUNDLE_IF_NONE = "RENDER_BUNDLE_IF_NONE";
|
||||
|
||||
protected static final String RENDER_BUNDLE_DOCUMENT_CONTENT = "RENDER_BUNDLE_DOCUMENT_CONTENT";
|
||||
protected static final String RENDER_BUNDLE_HEADER_DOC_ENTRY_URD = "RENDER_BUNDLE_HEADER_DOC_ENTRY_URD";
|
||||
protected static final String RENDER_BUNDLE_HEADER_DOC_ENTRY_U = "RENDER_BUNDLE_HEADER_DOC_ENTRY_U";
|
||||
protected static final String RENDER_BUNDLE_HEADER_DOC_ENTRY_RD = "RENDER_BUNDLE_HEADER_DOC_ENTRY_RD";
|
||||
|
||||
/** the plan here is to make this have it's own implementation of messages, rather than using the
|
||||
* validator messages, for better alignment with publisher I18n strategy
|
||||
|
|
|
@ -114,6 +114,9 @@ public class RendererFactory {
|
|||
if ("Library".equals(resource.getName())) {
|
||||
return new LibraryRenderer(context);
|
||||
}
|
||||
if ("Patient".equals(resource.getName())) {
|
||||
return new PatientRenderer(context);
|
||||
}
|
||||
if ("DiagnosticReport".equals(resource.getName())) {
|
||||
return new DiagnosticReportRenderer(context);
|
||||
}
|
||||
|
|
|
@ -158,9 +158,8 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
if (target.hasUserData("path")) {
|
||||
x.ah(target.getUserString("path")).tx(cr.present());
|
||||
} else {
|
||||
url = url.substring(0, url.indexOf("|"));
|
||||
x.code().tx(url);
|
||||
x.tx(": "+cr.present());
|
||||
x.tx(" ("+cr.present()+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,6 +413,8 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
if (id != null || lang != null || versionId != null || lastUpdated != null) {
|
||||
XhtmlNode p = plateStyle(div.para());
|
||||
p.tx("Resource ");
|
||||
p.tx(r.fhirType());
|
||||
p.tx(" ");
|
||||
if (id != null) {
|
||||
p.tx("\""+id+"\" ");
|
||||
}
|
||||
|
@ -489,4 +490,16 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
private String getPrimitiveValue(ResourceWrapper r, String name) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
return r.has(name) && r.getChildByName(name).hasValues() ? r.getChildByName(name).getValues().get(0).getBase().primitiveValue() : null;
|
||||
}
|
||||
|
||||
public void renderOrError(DomainResource dr) {
|
||||
try {
|
||||
render(dr);
|
||||
} catch (Exception e) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().tx("Error rendering: "+e.getMessage());
|
||||
dr.setText(null);
|
||||
inject(dr, x, NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -105,6 +105,7 @@ public class RenderingContext {
|
|||
private boolean canonicalUrlsAsLinks;
|
||||
private boolean pretty;
|
||||
private boolean header;
|
||||
private boolean contained;
|
||||
|
||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
private boolean noSlowLookup;
|
||||
|
@ -127,6 +128,8 @@ public class RenderingContext {
|
|||
private ZoneId timeZoneId;
|
||||
private DateTimeFormatter dateTimeFormat;
|
||||
private DateTimeFormatter dateFormat;
|
||||
private DateTimeFormatter dateYearFormat;
|
||||
private DateTimeFormatter dateYearMonthFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -151,6 +154,46 @@ public class RenderingContext {
|
|||
this.locale = new Locale.Builder().setLanguageTag("en-US").build();
|
||||
profileUtilities = new ProfileUtilities(worker, null, null);
|
||||
}
|
||||
public RenderingContext copy() {
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, specificationLink, localPrefix, lang, mode);
|
||||
|
||||
res.resolver = resolver;
|
||||
res.templateProvider = templateProvider;
|
||||
res.services = services;
|
||||
res.parser = parser;
|
||||
|
||||
res.headerLevelContext = headerLevelContext;
|
||||
res.canonicalUrlsAsLinks = canonicalUrlsAsLinks;
|
||||
res.pretty = pretty;
|
||||
res.contained = contained;
|
||||
|
||||
res.noSlowLookup = noSlowLookup;
|
||||
res.tooCostlyNoteEmpty = tooCostlyNoteEmpty;
|
||||
res.tooCostlyNoteNotEmpty = tooCostlyNoteNotEmpty;
|
||||
res.tooCostlyNoteEmptyDependent = tooCostlyNoteEmptyDependent;
|
||||
res.tooCostlyNoteNotEmptyDependent = tooCostlyNoteNotEmptyDependent;
|
||||
res.codeSystemPropList.addAll(codeSystemPropList);
|
||||
|
||||
res.profileUtilities = profileUtilities;
|
||||
res.definitionsTarget = definitionsTarget;
|
||||
res.destDir = destDir;
|
||||
res.addGeneratedNarrativeHeader = addGeneratedNarrativeHeader;
|
||||
res.questionnaireMode = questionnaireMode;
|
||||
res.header = header;
|
||||
res.selfLink = selfLink;
|
||||
res.inlineGraphics = inlineGraphics;
|
||||
res.timeZoneId = timeZoneId;
|
||||
res.dateTimeFormat = dateTimeFormat;
|
||||
res.dateFormat = dateFormat;
|
||||
res.dateYearFormat = dateYearFormat;
|
||||
res.dateYearMonthFormat = dateYearMonthFormat;
|
||||
res.targetVersion = targetVersion;
|
||||
res.locale = locale;
|
||||
|
||||
res.terminologyServiceOptions = terminologyServiceOptions.copy();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public IWorkerContext getContext() {
|
||||
return worker;
|
||||
|
@ -336,32 +379,6 @@ public class RenderingContext {
|
|||
return this;
|
||||
}
|
||||
|
||||
public RenderingContext copy() {
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, specificationLink, localPrefix, lang, mode);
|
||||
|
||||
res.resolver = resolver;
|
||||
res.templateProvider = templateProvider;
|
||||
res.services = services;
|
||||
res.parser = parser;
|
||||
|
||||
res.headerLevelContext = headerLevelContext;
|
||||
res.canonicalUrlsAsLinks = canonicalUrlsAsLinks;
|
||||
res.pretty = pretty;
|
||||
|
||||
res.noSlowLookup = noSlowLookup;
|
||||
res.tooCostlyNoteEmpty = tooCostlyNoteEmpty;
|
||||
res.tooCostlyNoteNotEmpty = tooCostlyNoteNotEmpty;
|
||||
res.tooCostlyNoteEmptyDependent = tooCostlyNoteEmptyDependent;
|
||||
res.tooCostlyNoteNotEmptyDependent = tooCostlyNoteNotEmptyDependent;
|
||||
res.codeSystemPropList.addAll(codeSystemPropList);
|
||||
|
||||
res.profileUtilities = profileUtilities;
|
||||
res.definitionsTarget = definitionsTarget;
|
||||
res.destDir = destDir;
|
||||
res.addGeneratedNarrativeHeader = addGeneratedNarrativeHeader;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean isInlineGraphics() {
|
||||
return inlineGraphics;
|
||||
|
@ -514,6 +531,30 @@ public class RenderingContext {
|
|||
this.dateFormat = DateTimeFormatter.ofPattern(dateFormat);
|
||||
}
|
||||
|
||||
public DateTimeFormatter getDateYearFormat() {
|
||||
return dateYearFormat;
|
||||
}
|
||||
|
||||
public void setDateYearFormat(DateTimeFormatter dateYearFormat) {
|
||||
this.dateYearFormat = dateYearFormat;
|
||||
}
|
||||
|
||||
public void setDateYearFormatString(String dateYearFormat) {
|
||||
this.dateYearFormat = DateTimeFormatter.ofPattern(dateYearFormat);
|
||||
}
|
||||
|
||||
public DateTimeFormatter getDateYearMonthFormat() {
|
||||
return dateYearMonthFormat;
|
||||
}
|
||||
|
||||
public void setDateYearMonthFormat(DateTimeFormatter dateYearMonthFormat) {
|
||||
this.dateYearMonthFormat = dateYearMonthFormat;
|
||||
}
|
||||
|
||||
public void setDateYearMonthFormatString(String dateYearMonthFormat) {
|
||||
this.dateYearMonthFormat = DateTimeFormatter.ofPattern(dateYearMonthFormat);
|
||||
}
|
||||
|
||||
public ResourceRendererMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
@ -521,6 +562,14 @@ public class RenderingContext {
|
|||
public void setMode(ResourceRendererMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public boolean isContained() {
|
||||
return contained;
|
||||
}
|
||||
|
||||
public void setContained(boolean contained) {
|
||||
this.contained = contained;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -18,6 +18,9 @@ public class Resolver {
|
|||
|
||||
public interface IReferenceResolver {
|
||||
ResourceWithReference resolve(RenderingContext context, String url);
|
||||
|
||||
// returns null if contained resource is inlined
|
||||
String urlForContained(RenderingContext context, String containingType, String containingId, String containedType, String containedId);
|
||||
}
|
||||
|
||||
public static class ResourceContext {
|
||||
|
|
|
@ -699,7 +699,6 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
boolean showCodeDetails, int indent, PropertyWrapper p, ElementDefinition child) throws UnsupportedEncodingException, IOException, EOperationOutcome {
|
||||
Map<String, String> displayHints = readDisplayHints(child);
|
||||
if ("DomainResource.contained".equals(child.getBase().getPath())) {
|
||||
System.out.print("-");
|
||||
// for (BaseWrapper v : p.getValues()) {
|
||||
// x.hr();
|
||||
// RenderingContext ctxt = context.clone();
|
||||
|
|
Loading…
Reference in New Issue