more WIP on rendering refactor

This commit is contained in:
Grahame Grieve 2024-06-17 22:40:52 +10:00
parent ef2531367e
commit b1a3141214
43 changed files with 2255 additions and 2115 deletions

View File

@ -35,6 +35,7 @@ import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
@ -1259,13 +1260,13 @@ public class StructureDefinitionComparer extends CanonicalResourceComparer imple
public XhtmlNode renderUnion(ProfileComparison comp, String id, String prefix, String corePath) throws FHIRException, IOException {
StructureDefinitionRenderer sdr = new StructureDefinitionRenderer(new RenderingContext(utilsLeft.getContext(), null, utilsLeft.getTerminologyServiceOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER).setPkp(this));
return sdr.generateTable(corePath, comp.union, false, prefix, false, id, true, corePath, prefix, false, true, null, false, sdr.getContext(), "u");
return sdr.generateTable(new RenderingStatus(), corePath, comp.union, false, prefix, false, id, true, corePath, prefix, false, true, null, false, sdr.getContext(), "u", null);
}
public XhtmlNode renderIntersection(ProfileComparison comp, String id, String prefix, String corePath) throws FHIRException, IOException {
StructureDefinitionRenderer sdr = new StructureDefinitionRenderer(new RenderingContext(utilsLeft.getContext(), null, utilsLeft.getTerminologyServiceOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER).setPkp(this));
return sdr.generateTable(corePath, comp.intersection, false, prefix, false, id, true, corePath, prefix, false, true, null, false, sdr.getContext(), "i");
return sdr.generateTable(new RenderingStatus(), corePath, comp.intersection, false, prefix, false, id, true, corePath, prefix, false, true, null, false, sdr.getContext(), "i", null);
}
private void genElementComp(String defPath, String anchorPrefix, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinitionNode> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
@ -1334,12 +1335,12 @@ public class StructureDefinitionComparer extends CanonicalResourceComparer imple
nc = sdrRight.genElementNameCell(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, false, ext, used , ref, sName, null);
}
if (combined.hasLeft()) {
frame(sdrLeft.genElementCells(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, true, ext, used , ref, sName, nc, false, false, sdrLeft.getContext(), children.size() > 0, defPath, anchorPrefix, new ArrayList<ElementDefinition>()), leftColor);
frame(sdrLeft.genElementCells(new RenderingStatus(), gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, true, ext, used , ref, sName, nc, false, false, sdrLeft.getContext(), children.size() > 0, defPath, anchorPrefix, new ArrayList<ElementDefinition>(), null), leftColor);
} else {
frame(spacers(row, 4, gen), leftColor);
}
if (combined.hasRight()) {
frame(sdrRight.genElementCells(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, true, ext, used, ref, sName, nc, false, false, sdrRight.getContext(), children.size() > 0, defPath, anchorPrefix, new ArrayList<ElementDefinition>()), rightColor);
frame(sdrRight.genElementCells(new RenderingStatus(), gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, true, ext, used, ref, sName, nc, false, false, sdrRight.getContext(), children.size() > 0, defPath, anchorPrefix, new ArrayList<ElementDefinition>(), null), rightColor);
} else {
frame(spacers(row, 4, gen), rightColor);
}

View File

@ -25,12 +25,11 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (ActorDefinition) r.getBase(), r);
} else {
throw new Error("ActorDefinitionRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (ActorDefinition) r);
}
@Override
@ -38,7 +37,7 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
return canonicalTitle(r);
}
public void render(RenderingStatus status, XhtmlNode x, ActorDefinition acd) throws FHIRFormatError, DefinitionException, IOException {
public void render(RenderingStatus status, XhtmlNode x, ActorDefinition acd, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException {
XhtmlNode tbl = x.table("grid");
XhtmlNode tr = tbl.tr();
tr.td().b().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_ACT, acd.getName()) + " ");
@ -52,18 +51,13 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
boolean first = true;
for (UrlType t : acd.getReference()) {
if (first) first = false; else x.br();
renderUri(status, td, wrap(t));
renderUri(status, td, wrapWC(r, t));
}
}
if (acd.hasCapabilities()) {
tbl.tr().td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_CAP));
td = tr.td().colspan("2");
CapabilityStatement cs = context.getWorker().fetchResource(CapabilityStatement.class, acd.getCapabilities(), acd);
if (cs != null) {
td.ah(cs.getWebPath()).tx(cs.present());
} else {
renderCanonical(status, wrap(acd), td, wrap(acd.getCapabilitiesElement()));
}
renderCanonical(status, r, td, CapabilityStatement.class, acd.getCapabilitiesElement());
}
if (acd.hasDerivedFrom()) {
tbl.tr().td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_DER));
@ -71,12 +65,7 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
boolean first = true;
for (UrlType t : acd.getReference()) {
if (first) first = false; else x.br();
ActorDefinition df = context.getWorker().fetchResource(ActorDefinition.class, t.getValue(), acd);
if (df != null) {
td.ah(df.getWebPath()).tx(df.present());
} else {
renderUri(status, td, wrap(t));
}
renderUri(status, r, td, t);
}
}
}

View File

@ -13,6 +13,7 @@ import javax.annotation.Nullable;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CapabilityStatement;
@ -57,12 +58,11 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (CapabilityStatement) r.getBase(), r);
} else {
throw new Error("CapabilityStatementRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (CapabilityStatement) r);
}
@Override
@ -288,7 +288,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
}
public void render(RenderingStatus status, XhtmlNode x, CapabilityStatement conf) throws FHIRFormatError, DefinitionException, IOException {
public void render(RenderingStatus status, XhtmlNode x, CapabilityStatement conf, ResourceElement res) throws FHIRFormatError, DefinitionException, IOException {
status.setExtensions(true);
boolean igRenderingMode = (context.getRules() == GenerationRules.IG_PUBLISHER);
FHIRVersion currentVersion = conf.getFhirVersion();
@ -308,7 +308,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
uList.li().addText(context.formatPhrase(RenderingContext.CAPABILITY_FHIR_VER, currentVersion.toCode()) + " ");
addSupportedFormats(uList, conf);
uList.li().addText(context.formatPhrase(RenderingContext.CAPABILITY_PUB_ON, displayDateTime(wrap(conf.getDateElement())) + " "));
uList.li().addText(context.formatPhrase(RenderingContext.CAPABILITY_PUB_ON, displayDateTime(wrapWC(res, conf.getDateElement())) + " "));
uList.li().addText(context.formatPhrase(RenderingContext.CAPABILITY_PUB_BY, conf.getPublisherElement().asStringValue()) + " ");
@ -317,7 +317,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
block.addTag("p").addText(context.formatPhrase(RenderingContext.CAPABILTY_ALLOW_CAP));
addSupportedCSs(x, conf);
addSupportedCSs(status, x, conf, res);
addSupportedIGs(x, conf);
int restNum = conf.getRest().size();
@ -348,7 +348,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
x.h(nextLevel,"resourcesCap" + Integer.toString(count)).addText(context.formatPhrase(RenderingContext.CAPABILITY_RES_PRO));
x.h(nextLevel+1,"resourcesSummary" + Integer.toString(count)).addText(context.formatPhrase(RenderingContext.GENERAL_SUMM));
addSummaryIntro(x);
addSummaryTable(x, rest, hasVRead, hasPatch, hasDelete, hasHistory, hasUpdates, count);
addSummaryTable(status, res, x, rest, hasVRead, hasPatch, hasDelete, hasHistory, hasUpdates, count);
x.addTag("hr");
//Third time for individual resources
int resCount = 1;
@ -427,19 +427,14 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
return null;
}
private void addSupportedCSs(XhtmlNode x, CapabilityStatement cap) {
private void addSupportedCSs(RenderingStatus status, XhtmlNode x, CapabilityStatement cap, ResourceElement res) throws UnsupportedEncodingException, IOException {
if (cap.hasInstantiates()) {
XhtmlNode p = x.para();
p.tx(cap.getInstantiates().size() > 1 ? "This CapabilityStatement instantiates these CapabilityStatements" : "This CapabilityStatement instantiates the CapabilityStatement");
boolean first = true;
for (CanonicalType ct : cap.getInstantiates()) {
CapabilityStatement cs = context.getContext().fetchResource(CapabilityStatement.class, ct.getValue(), cap);
if (first) {first = false;} else {p.tx(", ");};
if (cs == null) {
p.code().tx(ct.getValue());
} else {
p.ah(cs.getWebPath()).tx(cs.present());
}
renderCanonical(status, res, x, CapabilityStatement.class, ct);
}
}
if (cap.hasImports()) {
@ -447,13 +442,8 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
p.tx(cap.getImports().size() > 1 ? "This CapabilityStatement imports these CapabilityStatements" : "This CapabilityStatement imports the CapabilityStatement");
boolean first = true;
for (CanonicalType ct : cap.getImports()) {
CapabilityStatement cs = context.getContext().fetchResource(CapabilityStatement.class, ct.getValue(), cap);
if (first) {first = false;} else {p.tx(", ");};
if (cs == null) {
p.code().tx(ct.getValue());
} else {
p.ah(cs.getWebPath()).tx(cs.present());
}
renderCanonical(status, res, x, CapabilityStatement.class, ct);
}
}
}
@ -740,7 +730,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
uList.li().addText(context.formatPhrase(RenderingContext.CAPABILITY_RES_OPER));
}
private void addSummaryTable(XhtmlNode x, CapabilityStatement.CapabilityStatementRestComponent rest, boolean hasVRead, boolean hasPatch, boolean hasDelete, boolean hasHistory, boolean hasUpdates, int count) throws IOException {
private void addSummaryTable(RenderingStatus status, ResourceElement res, XhtmlNode x, CapabilityStatement.CapabilityStatementRestComponent rest, boolean hasVRead, boolean hasPatch, boolean hasDelete, boolean hasHistory, boolean hasUpdates, int count) throws IOException {
XhtmlNode t = x.div().attribute("class","table-responsive").table("table table-condensed table-hover");
XhtmlNode tr = t.addTag("thead").tr();
tr.th().b().tx(context.formatPhrase(RenderingContext.CAPABILITY_RES_TYP));
@ -788,12 +778,12 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
if (hasSupProf) {
profCell.br();
profCell.addTag("em").addText(context.formatPhrase(RenderingContext.CAPABILITY_ADD_SUPP_PROF));
renderSupportedProfiles(profCell, r);
renderSupportedProfiles(status, res, profCell, r);
}
}
else { //Case of only supported profiles
profCell.addText(context.formatPhrase(RenderingContext.CAPABILITY_SUPP_PROFS));
renderSupportedProfiles(profCell, r);
renderSupportedProfiles(status, res, profCell, r);
}
//Show capabilities
tr.td().addText(showOp(r, TypeRestfulInteraction.READ));
@ -839,16 +829,11 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
return paramNames;
}
private void renderSupportedProfiles(XhtmlNode profCell, CapabilityStatementRestResourceComponent r) throws IOException {
private void renderSupportedProfiles(RenderingStatus status, ResourceElement res, XhtmlNode profCell, CapabilityStatementRestResourceComponent r) throws IOException {
for (CanonicalType sp: r.getSupportedProfile()) {
profCell.br();
profCell.nbsp().nbsp();
StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, sp.getValue());
if (sd != null) {
profCell.ah(sd.getWebPath()).addText(sd.present());
} else {
profCell.ah(sp.getValue()).addText(sp.getValue());
}
renderCanonical(status, res, profCell, StructureDefinition.class, sp);
}
if (r.hasExtension(ToolingExtensions.EXT_PROFILE_MAPPING)) {
profCell.br();

View File

@ -10,6 +10,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.comparison.VersionComparisonAnnotation;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
@ -48,12 +49,11 @@ public class CodeSystemRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (CodeSystem) r.getBase(), r);
} else {
throw new Error("CodeSystemRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (CodeSystem) r);
}
@Override
@ -84,14 +84,14 @@ public class CodeSystemRenderer extends TerminologyRenderer {
private Boolean doMarkdown = null;
public void render(RenderingStatus status, XhtmlNode x, CodeSystem cs) throws FHIRFormatError, DefinitionException, IOException {
public void render(RenderingStatus status, XhtmlNode x, CodeSystem cs, ResourceElement res) throws FHIRFormatError, DefinitionException, IOException {
if (context.isHeader()) {
XhtmlNode h = x.h2();
h.addText(cs.hasTitle() ? cs.getTitle() : cs.getName());
addMarkdown(x, cs.getDescription());
if (cs.hasCopyright())
generateCopyright(x, cs );
generateCopyright(x, res);
}
boolean props = generateProperties(x, cs);

View File

@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CompartmentDefinition;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.CompartmentDefinition.CompartmentDefinitionResourceComponent;
@ -29,12 +30,11 @@ public class CompartmentDefinitionRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
throw new Error("StructureDefinitionRenderer only renders native resources directly");
if (r.isDirect()) {
render(status, x, (CompartmentDefinition) r.getBase());
} else {
throw new Error("CompartmentDefinitionRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (CompartmentDefinition) r);
}
@Override

View File

@ -13,6 +13,7 @@ import java.util.Map;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
@ -45,12 +46,11 @@ public class ConceptMapRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, r, x, (ConceptMap) r.getBase(), false);
} else {
throw new Error("ConceptMapRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (ConceptMap) r, false);
}
@Override
@ -323,7 +323,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
public void render(RenderingStatus status, XhtmlNode x, ConceptMap cm, boolean header) throws FHIRFormatError, DefinitionException, IOException {
public void render(RenderingStatus status, ResourceElement res, XhtmlNode x, ConceptMap cm, boolean header) throws FHIRFormatError, DefinitionException, IOException {
if (header) {
x.h2().addText(cm.getName()+" ("+cm.getUrl()+")");
}
@ -362,7 +362,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
first = false;
else
p.tx(", ");
addTelecom(p, c);
addTelecom(p, wrapWC(res, c));
}
}
p.tx(")");
@ -418,13 +418,13 @@ public class ConceptMapRenderer extends TerminologyRenderer {
pp.b().tx(context.formatPhrase(RenderingContext.CONC_MAP_GRP, gc) + " ");
pp.tx(context.formatPhrase(RenderingContext.CONC_MAP_FROM) + " ");
if (grp.hasSource()) {
renderCanonical(wrap(cm), pp, grp.getSource());
renderCanonical(status, res, pp, CodeSystem.class, grp.getSourceElement());
} else {
pp.code(context.formatPhrase(RenderingContext.CONC_MAP_CODE_SYS_UNSPEC));
}
pp.tx(" to ");
if (grp.hasTarget()) {
renderCanonical(wrap(cm), pp, grp.getTarget());
renderCanonical(status, res, pp, CodeSystem.class, grp.getTargetElement());
} else {
pp.code(context.formatPhrase(RenderingContext.CONC_MAP_CODE_SYS_UNSPEC));
}

View File

@ -16,82 +16,35 @@ import java.time.format.SignStyle;
import java.util.Currency;
import java.util.List;
import org.apache.commons.lang3.NotImplementedException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.Address;
import org.hl7.fhir.r5.model.Annotation;
import org.hl7.fhir.r5.model.Attachment;
import org.hl7.fhir.r5.model.BackboneType;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Base64BinaryType;
import org.hl7.fhir.r5.model.BaseDateTimeType;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.CodeableReference;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ContactDetail;
import org.hl7.fhir.r5.model.ContactPoint;
import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
import org.hl7.fhir.r5.model.DataRequirement;
import org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent;
import org.hl7.fhir.r5.model.DataRequirement.DataRequirementDateFilterComponent;
import org.hl7.fhir.r5.model.DataRequirement.DataRequirementSortComponent;
import org.hl7.fhir.r5.model.DataRequirement.SortDirection;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.DateType;
import org.hl7.fhir.r5.model.Dosage;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Expression;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.ExtensionHelper;
import org.hl7.fhir.r5.model.HumanName;
import org.hl7.fhir.r5.model.HumanName.NameUse;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.InstantType;
import org.hl7.fhir.r5.model.MarkdownType;
import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.Money;
import org.hl7.fhir.r5.model.NamingSystem;
import org.hl7.fhir.r5.model.Narrative;
import org.hl7.fhir.r5.model.Period;
import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Quantity;
import org.hl7.fhir.r5.model.Range;
import org.hl7.fhir.r5.model.Ratio;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.RelatedArtifact;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.SampledData;
import org.hl7.fhir.r5.model.Signature;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.Timing;
import org.hl7.fhir.r5.model.Timing.EventTiming;
import org.hl7.fhir.r5.model.Timing.TimingRepeatComponent;
import org.hl7.fhir.r5.model.Timing.UnitsOfTime;
import org.hl7.fhir.r5.model.TriggerDefinition;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.UsageContext;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
@ -506,32 +459,32 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
// 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(context.formatPhrase(RenderingContext.DATA_REND_UNRD_EX));
// }
// }
// 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(context.formatPhrase(RenderingContext.DATA_REND_UNRD_EX));
// }
// }
// 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(RenderingStatus status, XhtmlNode div, ResourceElement element, String sep) throws FHIRFormatError, DefinitionException, IOException {
boolean first = true;
for (ResourceElement ext : element.extensions()) {
@ -551,43 +504,43 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
// 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(context.formatPhrase(RenderingContext.DATA_REND_UNRD_EX));
// }
// }
// 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(context.formatPhrase(RenderingContext.DATA_REND_UNRD_EX));
// }
// }
// 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 ----------------------------------------------
@ -604,7 +557,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
public String displayDataType(DataType type) {
return displayDataType(wrap(type));
return displayDataType(wrapNC(type));
}
public String displayDataType(ResourceElement type) {
@ -661,8 +614,8 @@ public class DataRenderer extends Renderer implements CodeResolver {
if (type.has("display")) {
return type.primitiveValue("display");
} else if (type.has("reference")) {
// ResourceWithReference tr = resolveReference(res, r.getReference());
// x.addText(tr == null ? r.getReference() : "?ngen-3"); // getDisplayForReference(tr.getReference()));
// ResourceWithReference tr = resolveReference(res, r.getReference());
// x.addText(tr == null ? r.getReference() : "?ngen-3"); // getDisplayForReference(tr.getReference()));
return "?ngen-3";
} else {
return "?ngen-4?";
@ -752,24 +705,24 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
// public void renderDataType(RenderingStatus status, XhtmlNode x, ResourceElement type) throws FHIRFormatError, DefinitionException, IOException {
//// Base base = null;
//// try {
//// base = type.getBase();
//// } catch (FHIRException | IOException e) {
//// x.tx(context.formatPhrase(RenderingContext.DATA_REND_ERROR, e.getMessage()) + " "); // this shouldn't happen - it's an error in the library itself
//// return;
//// }
//// if (base instanceof DataType) {
//// render(x, (DataType) base);
//// } else {
//// x.tx(context.formatPhrase(RenderingContext.DATA_REND_TO_DO, base.fhirType()));
//// }
// }
// public void renderDataType(RenderingStatus status, XhtmlNode x, ResourceElement type) throws FHIRFormatError, DefinitionException, IOException {
//// Base base = null;
//// try {
//// base = type.getBase();
//// } catch (FHIRException | IOException e) {
//// x.tx(context.formatPhrase(RenderingContext.DATA_REND_ERROR, e.getMessage()) + " "); // this shouldn't happen - it's an error in the library itself
//// return;
//// }
//// if (base instanceof DataType) {
//// render(x, (DataType) base);
//// } else {
//// x.tx(context.formatPhrase(RenderingContext.DATA_REND_TO_DO, base.fhirType()));
//// }
// }
public void renderBase(RenderingStatus status, XhtmlNode x, Base b) throws FHIRFormatError, DefinitionException, IOException {
if (b instanceof DataType) {
renderDataType(status, x, wrap((DataType) b));
renderDataType(status, x, wrapNC((DataType) b));
} else {
x.tx(context.formatPhrase(RenderingContext.DATA_REND_NO_DISP, b.fhirType()) + " ");
}
@ -887,7 +840,16 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
protected void renderReference(RenderingStatus status, XhtmlNode x, ResourceElement ref) {
/**
* this is overriden in ResourceRenderer where a better rendering is performed
* @param status
* @param x
* @param ref
* @throws IOException
* @throws DefinitionException
* @throws FHIRFormatError
*/
protected void renderReference(RenderingStatus status, XhtmlNode x, ResourceElement ref) throws FHIRFormatError, DefinitionException, IOException {
if (ref.has("display")) {
x.tx(context.getTranslated(ref.child("display")));
} else if (ref.has("reference")) {
@ -896,27 +858,61 @@ public class DataRenderer extends Renderer implements CodeResolver {
x.tx("??");
}
}
//
// public void renderDateTime(RenderingStatus status, XhtmlNode x, Base e) {
// if (e.hasPrimitiveValue()) {
// x.addText(displayDateTime((DateTimeType) e));
// }
// }
//
// public void renderDate(RenderingStatus status, 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);
// x.addText(displayDateTime(dt));
// }
// }
//
// public void renderDateTime(RenderingStatus status, XhtmlNode x, Base e) {
// if (e.hasPrimitiveValue()) {
// x.addText(displayDateTime((DateTimeType) e));
// }
// }
//
// public void renderDate(RenderingStatus status, 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);
// x.addText(displayDateTime(dt));
// }
// }
protected boolean renderPrimitiveWithNoValue(RenderingStatus status, XhtmlNode x, PrimitiveType<?> prim) throws FHIRFormatError, DefinitionException, IOException {
if (prim.hasPrimitiveValue()) {
return false;
}
boolean first = true;
for (Extension ext : prim.getExtension()) {
if (first) first = false; else x.tx(", ");
String url = ext.getUrl();
if (url.equals(ToolingExtensions.EXT_DAR)) {
x.tx("Absent because : ");
displayCode(x, wrapNC(ext.getValue()));
} else if (url.equals(ToolingExtensions.EXT_NF)) {
x.tx("Null because: ");
displayCode(x, wrapNC(ext.getValue()));
} else if (url.equals(ToolingExtensions.EXT_OT)) {
x.code().tx("Text: ");
displayCode(x, wrapNC(ext.getValue()));
} else if (url.equals(ToolingExtensions.EXT_CQF_EXP)) {
x.code().tx("Value calculated by: ");
renderExpression(status, x, wrapNC(ext.getValue()));
} else {
StructureDefinition def = context.getContext().fetchResource(StructureDefinition.class, url);
if (def == null) {
x.code().tx(tail(url)+": ");
} else {
x.code().tx(def.present()+": ");
}
renderDataType(status, x, wrapNC(ext.getValue()));
}
}
status.setExtensions(true);
return true;
}
protected boolean renderPrimitiveWithNoValue(RenderingStatus status, XhtmlNode x, ResourceElement prim) throws FHIRFormatError, DefinitionException, IOException {
if (prim.hasPrimitiveValue()) {
return false;
@ -953,7 +949,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
private String tail(String url) {
return url.contains("/") ? url.substring(url.lastIndexOf("/")+1) : url;
}
}
private void displayCode(XhtmlNode x, ResourceElement code) {
x.tx(code.primitiveValue());
@ -986,37 +982,6 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
protected void renderUri(RenderingStatus status, XhtmlNode x, UriType uriD, String path, String id, Resource src) {
String uri = uriD.getValue();
if (isCanonical(path)) {
x.code().tx(uri);
} else {
if (uri == null) {
x.b().tx(uri);
} else if (uri.startsWith("mailto:")) {
x.ah(uri).addText(uri.substring(7));
} else {
Resource target = context.getContext().fetchResource(Resource.class, uri, src);
if (target != null && target.hasWebPath()) {
String title = target instanceof CanonicalResource ? crPresent((CanonicalResource) target) : uri;
x.ah(target.getWebPath()).addText(title);
} else {
String url = context.getResolver() != null ? context.getResolver().resolveUri(context, uri) : null;
if (url != null) {
x.ah(url).addText(uri);
} else if (uri.contains("|")) {
x.ah(uri.substring(0, uri.indexOf("|"))).addText(uri);
} else if (uri.startsWith("http:") || uri.startsWith("https:") || uri.startsWith("ftp:")) {
x.ah(uri).addText(uri);
} else {
x.code().addText(uri);
}
}
}
}
}
protected void renderAnnotation(RenderingStatus status, XhtmlNode x, ResourceElement annot) {
renderAnnotation(status, x, annot, false);
}
@ -1108,7 +1073,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
public String displayCoding(List<Coding> list) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Coding c : list) {
b.append(displayCoding(wrap(c)));
b.append(displayCoding(wrapNC(c)));
}
return b.toString();
}
@ -1139,6 +1104,28 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
protected void renderCoding(HierarchicalTableGenerator gen, List<Piece> pieces, ResourceElement c) {
if (c.isEmpty()) {
return;
}
String url = getLinkForSystem(c.primitiveValue("system"), c.primitiveValue("version"));
String name = displayCodeSource(c.primitiveValue("system"), c.primitiveValue("version"));
if (!Utilities.noString(url)) {
pieces.add(gen.new Piece(url, name, c.primitiveValue("system")+(c.has("version") ? "#"+c.primitiveValue("version") : "")));
} else {
pieces.add(gen.new Piece(null, name, c.primitiveValue("system")+(c.has("version") ? "#"+c.primitiveValue("version") : "")));
}
pieces.add(gen.new Piece(null, "#"+c.primitiveValue("code"), null));
String s = context.getTranslated(c.child("display"));
if (Utilities.noString(s)) {
s = lookupCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code"));
}
if (!Utilities.noString(s)) {
pieces.add(gen.new Piece(null, " \""+s+"\"", null));
}
}
private String getLinkForSystem(String system, String version) {
if ("http://snomed.info/sct".equals(system)) {
return "https://browser.ihtsdotools.org/";
@ -1226,7 +1213,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
public CodeResolution resolveCode(Coding code) {
return resolveCode(wrap(code));
return resolveCode(wrapNC(code));
}
public CodeResolution resolveCode(CodeableConcept code) {
@ -1310,20 +1297,17 @@ public class DataRenderer extends Renderer implements CodeResolver {
return s;
}
protected void renderCodeableConcept(RenderingStatus status, XhtmlNode x, ResourceElement cc) throws FHIRFormatError, DefinitionException, IOException {
renderCodeableConcept(status, x, cc, false);
}
protected void renderCodeableReference(RenderingStatus status, XhtmlNode x, ResourceElement e, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
protected void renderCodeableReference(RenderingStatus status, XhtmlNode x, ResourceElement e) throws FHIRFormatError, DefinitionException, IOException {
if (e.has("concept")) {
renderCodeableConcept(status, x, e.child("concept"), showCodeDetails);
renderCodeableConcept(status, x, e.child("concept"));
}
if (e.has("reference")) {
renderReference(status, x, e.child("reference"));
}
}
protected void renderCodeableConcept(RenderingStatus status, XhtmlNode x, ResourceElement cc, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
protected void renderCodeableConcept(RenderingStatus status, XhtmlNode x, ResourceElement cc) throws FHIRFormatError, DefinitionException, IOException {
if (cc.isEmpty()) {
return;
}
@ -1355,7 +1339,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
s = cc.children("coding").get(0).primitiveValue("code");
}
if (showCodeDetails) {
if (status.isShowCodeDetails()) {
x.addText(s+" ");
XhtmlNode sp = x.span("background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki", null);
sp.tx(" (");
@ -1597,7 +1581,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
numberFormat.setMaximumFractionDigits(c.getDefaultFractionDigits());
numberFormat.setMinimumFractionDigits(c.getDefaultFractionDigits());
return numberFormat.format(input);
}
}
protected void renderMoney(RenderingStatus status, XhtmlNode x, ResourceElement money) {
if (x.getName().equals("blockquote")) {
@ -1708,18 +1692,20 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
}
protected void addTelecom(XhtmlNode p, ContactPoint c) {
if (c.getSystem() == ContactPointSystem.PHONE) {
p.tx(context.formatPhrase(RenderingContext.DATA_REND_PHONE, c.getValue()) + " ");
} else if (c.getSystem() == ContactPointSystem.FAX) {
p.tx(context.formatPhrase(RenderingContext.DATA_REND_FAX, c.getValue()) + " ");
} else if (c.getSystem() == ContactPointSystem.EMAIL) {
p.ah("mailto:"+c.getValue()).addText(c.getValue());
} else if (c.getSystem() == ContactPointSystem.URL) {
if (c.getValue().length() > 30)
p.ah(c.getValue()).addText(c.getValue().substring(0, 30)+"...");
protected void addTelecom(XhtmlNode p, ResourceElement c) {
String sys = c.primitiveValue("system");
String value = c.primitiveValue("value");
if (sys.equals("phone")) {
p.tx(context.formatPhrase(RenderingContext.DATA_REND_PHONE, value) + " ");
} else if (sys.equals("fax")) {
p.tx(context.formatPhrase(RenderingContext.DATA_REND_FAX, value) + " ");
} else if (sys.equals("email")) {
p.ah("mailto:"+value).addText(value);
} else if (sys.equals("url")) {
if (value.length() > 30)
p.ah(value).addText(value.substring(0, 30)+"...");
else
p.ah(c.getValue()).addText(c.getValue());
p.ah(value).addText(value);
}
}
private static String describeSystem(String system) {
@ -1770,8 +1756,12 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
protected void renderQuantity(HierarchicalTableGenerator gen, List<Piece> pieces, ResourceElement q, boolean showCodeDetails) {
pieces.add(gen.new Piece(null, displayQuantity(q), null));
}
protected void renderQuantity(HierarchicalTableGenerator gen, List<Piece> pieces, Quantity q, boolean showCodeDetails) {
pieces.add(gen.new Piece(null, displayQuantity(wrap(q)), null));
pieces.add(gen.new Piece(null, displayQuantity(wrapNC(q)), null));
}
public String displayRange(ResourceElement q) {

View File

@ -12,10 +12,6 @@ import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.DiagnosticReport;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.DirectWrappers;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
@ -28,8 +24,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
public class ObservationNode {
private String ref;
private String reference;
private ResourceElement resource;
private ResourceWithReference resolution;
private List<ObservationNode> contained;
}
@ -87,7 +82,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
List<ResourceElement> items = dr.children("result");
if (!items.isEmpty()) {
List<ObservationNode> observations = fetchObservations(items, dr);
List<ObservationNode> observations = fetchObservations(items);
buildObservationsTable(status, x, observations, eff, iss);
}
@ -136,11 +131,11 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private void populateSubjectSummary(RenderingStatus status, XhtmlNode container, ResourceElement subject) throws UnsupportedEncodingException, FHIRException, IOException, EOperationOutcome {
ResourceElement r = fetchResource(subject);
ResourceWithReference r = resolveReference(subject);
if (r == null)
container.tx(context.formatPhrase(RenderingContext.DIAG_REP_REND_UNABLE));
else if (r.fhirType().equals("Patient"))
generatePatientSummary(container, r);
else if (r.getResource().fhirType().equals("Patient"))
generatePatientSummary(container, r.getResource());
else
container.tx(context.formatPhrase(RenderingContext.GENERAL_TODO));
}
@ -149,17 +144,17 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
new PatientRenderer(context).describe(c, r);
}
private List<ObservationNode> fetchObservations(List<ResourceElement> list, ResourceElement rw) throws UnsupportedEncodingException, FHIRException, IOException {
private List<ObservationNode> fetchObservations(List<ResourceElement> list) throws UnsupportedEncodingException, FHIRException, IOException {
List<ObservationNode> res = new ArrayList<ObservationNode>();
for (ResourceElement b : list) {
if (b.has("reference")) {
ObservationNode obs = new ObservationNode();
obs.ref = b.get("reference").primitiveValue();
obs.obs = resolveReference(rw, obs.ref);
if (obs.obs != null && obs.obs.getResource() != null) {
PropertyWrapper t = getProperty(obs.obs.getResource(), "contained");
if (t != null && t.hasValues()) {
obs.contained = fetchObservations(t.getValues(), rw);
obs.ref = b.primitiveValue("reference");
obs.resolution = resolveReference(b.child("reference"));
if (obs.resolution != null && obs.resolution.getResource() != null) {
List<ResourceElement> t = obs.resolution.getResource().children("contained");
if (!t.isEmpty()) {
obs.contained = fetchObservations(t);
}
}
res.add(obs);
@ -206,7 +201,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private boolean scanObsForRefRange(List<ObservationNode> observations) {
for (ObservationNode o : observations) {
ResourceElement obs = o.resource;
ResourceElement obs = o.resolution.getResource();
if (obs != null && obs.has("referenceRange")) {
return true;
}
@ -221,7 +216,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private boolean scanObsForNote(List<ObservationNode> observations) {
for (ObservationNode o : observations) {
ResourceElement obs = o.resource;
ResourceElement obs = o.resolution.getResource();
if (obs != null && obs.has("note")) {
return true;
}
@ -236,7 +231,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private boolean scanObsForIssued(List<ObservationNode> observations, ResourceElement iss) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
ResourceElement obs = o.resource;
ResourceElement obs = o.resolution.getResource();
if (obs != null && obs.has("issued") && (iss == null || !iss.matches(obs.child("issued")))) {
return true;
}
@ -251,7 +246,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private boolean scanObsForEffective(List<ObservationNode> observations, ResourceElement eff) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
ResourceElement obs = o.resource;
ResourceElement obs = o.resolution.getResource();
if (obs != null && obs.has("effective[x]") && (eff == null || !eff.matches(obs.child("effective[x]")))) {
return true;
}
@ -266,7 +261,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private boolean scanObsForFlags(List<ObservationNode> observations) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
ResourceElement obs = o.resource;
ResourceElement obs = o.resolution.getResource();
if (obs != null && (obs.has("interpretation") || obs.has("status"))) {
return true;
}
@ -281,12 +276,12 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
private void addObservationToTable(RenderingStatus status, XhtmlNode tbl, ObservationNode o, int i, String cs, boolean refRange, boolean flags, boolean note, boolean effectiveTime, boolean issued, ResourceElement eff, ResourceElement iss) throws UnsupportedEncodingException, FHIRException, IOException {
XhtmlNode tr = tbl.tr();
if (o.reference == null) {
if (o.resolution == null) {
XhtmlNode td = tr.td().colspan(cs);
td.i().tx(context.formatPhrase(RenderingContext.DIAG_REP_REND_NOTRES));
} else {
if (o.resource != null) {
addObservationToTable(status, tr, o.resource, i, o.reference, refRange, flags, note, effectiveTime, issued, eff, iss);
if (o.resolution.getResource() != null) {
addObservationToTable(status, tr, o.resolution.getResource(), i, o.resolution.getReference(), refRange, flags, note, effectiveTime, issued, eff, iss);
} else {
XhtmlNode td = tr.td().colspan(cs);
td.i().tx(context.formatPhrase(RenderingContext.DIAG_REP_REND_OBS));

View File

@ -13,12 +13,10 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class EncounterRenderer extends ResourceRenderer {
public EncounterRenderer(RenderingContext context) {
super(context);
}
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return "todo";

View File

@ -35,12 +35,11 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (ExampleScenario) r.getBase(), r);
} else {
throw new Error("ExampleScenarioRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (ExampleScenario) r);
}
@Override
@ -48,17 +47,17 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return canonicalTitle(r);
}
public void render(RenderingStatus status, XhtmlNode x, ExampleScenario scen) throws FHIRException {
public void render(RenderingStatus status, XhtmlNode x, ExampleScenario scen, ResourceElement res) throws FHIRException {
try {
if (context.getScenarioMode() == null) {
renderActors(status, x, scen);
renderActors(status, res, x, scen);
} else {
switch (context.getScenarioMode()) {
case ACTORS:
renderActors(status, x, scen);
renderActors(status, res, x, scen);
break;
case INSTANCES:
renderInstances(status, x, scen);
renderInstances(status, res, x, scen);
break;
case PROCESSES:
renderProcesses(status, x, scen);
@ -72,8 +71,8 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
}
}
public String renderDiagram(ExampleScenario scen) throws IOException {
String plantUml = toPlantUml(scen);
public String renderDiagram(RenderingStatus status, ResourceElement res, ExampleScenario scen) throws IOException {
String plantUml = toPlantUml(status, res, scen);
SourceStringReader reader = new SourceStringReader(plantUml);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
reader.outputImage(os, new FileFormatOption(FileFormat.SVG));
@ -83,7 +82,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return svg;
}
protected String toPlantUml(ExampleScenario scen) throws IOException {
protected String toPlantUml(RenderingStatus status, ResourceElement res, ExampleScenario scen) throws IOException {
String plantUml = "@startuml\r\n";
plantUml += "Title " + (scen.hasTitle() ? scen.getTitle() : scen.getName()) + "\r\n\r\n";
Map<String, String> actorKeys = new HashMap<String, String>();
@ -97,7 +96,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
int processNum = 1;
for (ExampleScenarioProcessComponent process: scen.getProcess()) {
plantUml += toPlantUml(process, Integer.toString(processNum), scen, actorKeys);
plantUml += toPlantUml(status, res, process, Integer.toString(processNum), scen, actorKeys);
processNum++;
}
plantUml += "@enduml";
@ -115,7 +114,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return new String(chars);
}
protected String toPlantUml(ExampleScenarioProcessComponent process, String prefix, ExampleScenario scen, Map<String, String> actorKeys) throws IOException {
protected String toPlantUml(RenderingStatus status, ResourceElement res, ExampleScenarioProcessComponent process, String prefix, ExampleScenario scen, Map<String, String> actorKeys) throws IOException {
String plantUml = "group " + process.getTitle() + " " + creolLink("details", "#p_" + prefix, process.getDescription()) + "\r\n";
Map<String,Boolean> actorsActive = new HashMap<String, Boolean>();
@ -124,7 +123,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
}
int stepCount = 1;
for (ExampleScenarioProcessStepComponent step: process.getStep()) {
plantUml += toPlantUml(step, stepPrefix(prefix, step, stepCount), scen, actorsActive, actorKeys);
plantUml += toPlantUml(status, res, step, stepPrefix(prefix, step, stepCount), scen, actorsActive, actorKeys);
if (step.getPause())
plantUml += context.formatPhrase(RenderingContext.EX_SCEN_TIME)+"\n";
stepCount++;
@ -134,15 +133,15 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return plantUml;
}
protected String toPlantUml(ExampleScenarioProcessStepComponent step, String prefix, ExampleScenario scen, Map<String,Boolean> actorsActive, Map<String, String> actorKeys) throws IOException {
protected String toPlantUml(RenderingStatus status, ResourceElement res, ExampleScenarioProcessStepComponent step, String prefix, ExampleScenario scen, Map<String,Boolean> actorsActive, Map<String, String> actorKeys) throws IOException {
String plantUml = "";
if (step.hasWorkflow()) {
XhtmlNode n = new XhtmlDocument();
renderCanonical(wrap(scen), n, step.getWorkflow());
renderCanonical(status, res, n, Resource.class, step.getWorkflowElement());
XhtmlNode ref = n.getChildNodes().get(0);
plantUml += noteOver(scen.getActor(), context.formatPhrase(RenderingContext.EXAMPLE_SCEN_STEP_SCEN, trimPrefix(prefix), creolLink((ref.getContent()), ref.getAttribute("href"))));
} else if (step.hasProcess())
plantUml += toPlantUml(step.getProcess(), prefix, scen, actorKeys);
plantUml += toPlantUml(status, res, step.getProcess(), prefix, scen, actorKeys);
else {
// Operation
plantUml += toPlantUml(step.getOperation(), prefix, scen, actorsActive, actorKeys);
@ -229,7 +228,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return s;
}
public boolean renderActors(RenderingStatus status, XhtmlNode x, ExampleScenario scen) throws IOException {
public boolean renderActors(RenderingStatus status, ResourceElement res, XhtmlNode x, ExampleScenario scen) throws IOException {
XhtmlNode tbl = x.table("table-striped table-bordered");
XhtmlNode thead = tbl.tr();
thead.th().addText(context.formatPhrase(RenderingContext.GENERAL_NAME));
@ -246,7 +245,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
return true;
}
public boolean renderInstances(RenderingStatus status, XhtmlNode x, ExampleScenario scen) throws IOException {
public boolean renderInstances(RenderingStatus status, ResourceElement res, XhtmlNode x, ExampleScenario scen) throws IOException {
XhtmlNode tbl = x.table("table-striped table-bordered");
XhtmlNode thead = tbl.tr();
thead.th().addText(context.formatPhrase(RenderingContext.GENERAL_NAME));
@ -276,24 +275,29 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
if (!instance.hasStructureVersion() || instance.getStructureType().getSystem().equals("")) {
if (instance.hasStructureVersion())
typeCell.tx((context.formatPhrase(RenderingContext.EX_SCEN_FVER, instance.getStructureVersion()) + " ") + " ");
if (instance.hasStructureProfile()) {
renderCanonical(wrap(scen), typeCell, instance.getStructureProfile().toString());
if (instance.hasStructureProfileCanonicalType()) {
renderCanonical(status, res, typeCell, StructureDefinition.class, instance.getStructureProfileCanonicalType());
} else if (instance.hasStructureProfileUriType()) {
renderBase(status, typeCell, instance.getStructureProfileUriType());
} else {
renderCanonical(wrap(scen), typeCell, "http://hl7.org/fhir/StructureDefinition/" + instance.getStructureType().getCode());
CanonicalType ct = new CanonicalType("http://hl7.org/fhir/StructureDefinition/" + instance.getStructureType().getCode());
renderCanonical(status, res, typeCell, StructureDefinition.class, ct);
}
} else {
renderDataType(status, typeCell, wrap(instance.getStructureVersionElement()));
renderDataType(status, typeCell, wrapWC(res, instance.getStructureVersionElement()));
typeCell.tx(" "+(context.formatPhrase(RenderingContext.GENERAL_VER_LOW, instance.getStructureVersion())+" "));
if (instance.hasStructureProfile()) {
typeCell.tx(" ");
renderCanonical(wrap(scen), typeCell, instance.getStructureProfile().toString());
if (instance.hasStructureProfileCanonicalType()) {
renderCanonical(status, res, typeCell, StructureDefinition.class, instance.getStructureProfileCanonicalType());
}
}
}
if (instance.hasContent() && instance.getContent().hasReference()) {
// Force end-user mode to avoid ugly references
RenderingContext.ResourceRendererMode mode = context.getMode();
context.setMode(RenderingContext.ResourceRendererMode.END_USER);
renderReference(status, wrap(scen), row.td(), wrap(instance.getContent().copy().setDisplay("here")));
renderReference(status, row.td(), wrapWC(res, instance.getContent().copy().setDisplay("here")));
context.setMode(mode);
} else
row.td();
@ -328,7 +332,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
// Force end-user mode to avoid ugly references
RenderingContext.ResourceRendererMode mode = context.getMode();
context.setMode(RenderingContext.ResourceRendererMode.END_USER);
renderReference(status, wrap(scen), row.td(), wrap(version.getContent().copy().setDisplay("here")));
renderReference(status, row.td(), wrapWC(res, version.getContent().copy().setDisplay("here")));
context.setMode(mode);
} else
row.td();
@ -445,7 +449,7 @@ public class ExampleScenarioRenderer extends TerminologyRenderer {
name.tx(op.getTitle());
if (op.hasType()) {
name.tx(" - ");
renderCoding(status, name, wrap(op.getType()));
renderCoding(status, name, wrapNC(op.getType()));
}
XhtmlNode descCell = row.td();
addMarkdown(descCell, op.getDescription());

View File

@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.ImplementationGuide;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
@ -21,12 +22,11 @@ public class ImplementationGuideRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (ImplementationGuide) r.getBase());
} else {
throw new Error("ImplementationGuideRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (ImplementationGuide) r);
}
@Override

View File

@ -77,7 +77,7 @@ public class LibraryRenderer extends ResourceRenderer {
citation = citation || ra.has("citation");
}
for (ResourceElement ra : artifacts) {
renderArtifact(t, ra, lib, label, display, citation);
renderArtifact(status, t, ra, lib, label, display, citation);
}
}
List<ResourceElement> parameters = lib.children("parameter");
@ -157,7 +157,7 @@ public class LibraryRenderer extends ResourceRenderer {
}
private void renderArtifact(XhtmlNode t, ResourceElement ra, ResourceElement lib, boolean label, boolean display, boolean citation) throws UnsupportedEncodingException, FHIRException, IOException {
private void renderArtifact(RenderingStatus status, XhtmlNode t, ResourceElement ra, ResourceElement lib, boolean label, boolean display, boolean citation) throws UnsupportedEncodingException, FHIRException, IOException {
XhtmlNode tr = t.tr();
tr.td().tx(ra.has("type") ? ra.primitiveValue("type") : null);
if (label) {
@ -170,7 +170,7 @@ public class LibraryRenderer extends ResourceRenderer {
tr.td().markdown(ra.has("citation") ? ra.primitiveValue("citation") : null, "Citation");
}
if (ra.has("resource")) {
renderCanonical(lib, tr.td(), ra.primitiveValue("resource"));
renderCanonical(status, tr.td(), Resource.class, ra.child("resource"));
} else {
tr.td().tx(ra.has("url") ? ra.primitiveValue("url") : null);
}

View File

@ -95,9 +95,9 @@ public class LiquidRenderer extends ResourceRenderer implements ILiquidRendering
LiquidRendererContext ctxt = (LiquidRendererContext) appContext;
ResourceElement r = null;
if (base instanceof Element) {
r = new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), (Element) base);
r = ResourceElement.forType(context.getContextUtilities(), context.getProfileUtilities(), (Element) base);
} else if (base instanceof DataType) {
r = new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), (DataType) base);
r = ResourceElement.forType(context.getContextUtilities(), context.getProfileUtilities(), (DataType) base);
} else {
return base.toString();
}

View File

@ -48,15 +48,15 @@ public class ListRenderer extends ResourceRenderer {
td = tr.td();
if (list.has("subject")) {
td.tx(context.formatPhrase(RenderingContext.LIST_REND_SUB)+" ");
shortForRef(td, list.child("subject"));
renderReference(status, td, list.child("subject"));
}
if (list.has("encounter")) {
td.tx(context.formatPhrase(RenderingContext.LIST_REND_ENC)+" ");
shortForRef(td, list.child("encounter"));
renderReference(status, td, list.child("encounter"));
}
if (list.has("source")) {
td.tx(context.formatPhrase(RenderingContext.GENERAL_SRC)+" ");
shortForRef(td, list.child("encounter"));
renderReference(status, td, list.child("encounter"));
}
if (list.has("orderedBy")) {
td.tx(context.formatPhrase(RenderingContext.LIST_REND_ORD, displayDataType(list.child("orderedBy")))+" ");
@ -86,7 +86,7 @@ public class ListRenderer extends ResourceRenderer {
}
for (ResourceElement e : list.children("entry")) {
tr = t.tr();
shortForRef(tr.td(), e.child("item"));
renderReference(status, tr.td(), e.child("item"));
if (date) {
tr.td().tx(e.has("date") ? displayDateTime(e.child("date")) : "");
}
@ -107,13 +107,5 @@ public class ListRenderer extends ResourceRenderer {
return list.getTitle();
}
private void shortForRef(XhtmlNode x, ResourceElement ref) throws UnsupportedEncodingException, IOException {
ResourceWithReference r = context.getResolver() == null ? null : context.getResolver().resolve(context, ref.primitiveValue("reference"));
if (r == null) {
x.tx(displayReference(ref));
} else {
x.ah(r.getReference()).tx(RendererFactory.factory(r.getResource().fhirType(), context).displayResource(r.getResource()));
}
}
}

View File

@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.NamingSystem;
@ -28,12 +29,11 @@ public class NamingSystemRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (NamingSystem) r.getBase());
} else {
throw new Error("NamingSystemRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (NamingSystem) r);
}
@Override

View File

@ -28,6 +28,7 @@ import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
import org.hl7.fhir.r5.renderers.ObligationsRenderer.ObligationDetail;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.utils.PublicationHacker;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.MarkDownProcessor;
@ -288,24 +289,24 @@ public class ObligationsRenderer extends Renderer {
return abr;
}
public String render(RenderingStatus status, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws IOException {
public String render(RenderingStatus status, ResourceElement res, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws IOException {
if (obligations.isEmpty()) {
return "";
} else {
XhtmlNode tbl = new XhtmlNode(NodeType.Element, "table");
tbl.attribute("class", "grid");
renderTable(status, tbl.getChildNodes(), true, defPath, anchorPrefix, inScopeElements);
renderTable(status, res, tbl.getChildNodes(), true, defPath, anchorPrefix, inScopeElements);
return new XhtmlComposer(false).compose(tbl);
}
}
public void renderTable(RenderingStatus status, HierarchicalTableGenerator gen, Cell c, List<ElementDefinition> inScopeElements) throws FHIRFormatError, DefinitionException, IOException {
public void renderTable(RenderingStatus status, ResourceElement res, HierarchicalTableGenerator gen, Cell c, List<ElementDefinition> inScopeElements) throws FHIRFormatError, DefinitionException, IOException {
if (obligations.isEmpty()) {
return;
} else {
Piece piece = gen.new Piece("table").attr("class", "grid");
c.getPieces().add(piece);
renderTable(status, piece.getChildren(), false, gen.getDefPath(), gen.getAnchorPrefix(), inScopeElements);
renderTable(status, res, piece.getChildren(), false, gen.getDefPath(), gen.getAnchorPrefix(), inScopeElements);
}
}
@ -360,7 +361,7 @@ public class ObligationsRenderer extends Renderer {
}
public void renderTable(RenderingStatus status, List<XhtmlNode> children, boolean fullDoco, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws FHIRFormatError, DefinitionException, IOException {
public void renderTable(RenderingStatus status, ResourceElement res, List<XhtmlNode> children, boolean fullDoco, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws FHIRFormatError, DefinitionException, IOException {
boolean doco = false;
boolean usage = false;
boolean actor = false;
@ -485,7 +486,7 @@ public class ObligationsRenderer extends Renderer {
XhtmlNode td = tr.td();
for (UsageContext u : ob.usage) {
if (first) first = false; else td.tx(", ");
new DataRenderer(context).renderDataType(status, td, wrap(u));
new DataRenderer(context).renderDataType(status, td, wrapWC(res, u));
}
} else {
tr.td();

View File

@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeType;
@ -40,12 +41,11 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (OperationDefinition) r.getBase());
} else {
throw new Error("OperationDefinitionRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (OperationDefinition) r);
}
@Override

View File

@ -252,7 +252,7 @@ public class PatientRenderer extends ResourceRenderer {
}
for (String url : extensions.keySet()) {
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, url);
StructureDefinition sd = findCanonical(StructureDefinition.class, url, r);
if (sd != null) {
List<ResourceElement> list = extensions.get(url);
boolean anyComplex = false;

View File

@ -64,14 +64,6 @@ import org.hl7.fhir.r5.model.Timing;
import org.hl7.fhir.r5.model.TriggerDefinition;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.UsageContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
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.ResourceWithReference;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
@ -378,7 +370,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
if ("DomainResource.contained".equals(child.getBase().getPath())) {
if (round2) {
for (ResourceElement v : p.getValues()) {
if (v.getResource() != null && !RendererFactory.hasSpecificRenderer(v.fhirType())) {
if (v.getResourceWrapper() != null && !RendererFactory.hasSpecificRenderer(v.fhirType())) {
x.hr();
RenderingContext ctxt = context.copy();
ctxt.setContained(true);

View File

@ -112,11 +112,11 @@ public class ProvenanceRenderer extends ResourceRenderer {
if (tl.size() == 0) {
tr.td();
} else if (tl.size() == 1) {
renderCodeableConcept(status, tr.td(), tl.get(0), false);
renderCodeableConcept(status, tr.td(), tl.get(0));
} else {
XhtmlNode ul = tr.td().ul();
for (ResourceElement cc : tl) {
renderCodeableConcept(status, ul.li(), cc, false);
renderCodeableConcept(status, ul.li(), cc);
}
}
}

View File

@ -4,8 +4,9 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.Expression;
import org.hl7.fhir.r5.model.Questionnaire;
import org.hl7.fhir.r5.model.QuestionnaireResponse;
@ -13,11 +14,11 @@ import org.hl7.fhir.r5.model.QuestionnaireResponse.QuestionnaireResponseItemAnsw
import org.hl7.fhir.r5.model.QuestionnaireResponse.QuestionnaireResponseItemComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
@ -33,35 +34,31 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
super(context);
}
public boolean render(XhtmlNode x, Resource q) throws UnsupportedEncodingException, IOException {
return render(x, (QuestionnaireResponse) q);
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return "todo";
}
public boolean render(XhtmlNode x, QuestionnaireResponse q) throws UnsupportedEncodingException, IOException {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement qr) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
switch (context.getQuestionnaireMode()) {
case FORM: return renderForm(x, q);
case LINKS: return renderLinks(x, q);
case FORM:
renderTree(status, x, qr);
break;
case LINKS:
renderLinks(status, x, qr);
break;
// case LOGIC: return renderLogic(x, q);
// case DEFNS: return renderDefns(x, q);
case TREE: return renderTree(x, q);
case TREE:
renderTree(status, x, qr);
break;
default:
throw new Error(context.formatPhrase(RenderingContext.QUEST_UNKNOWN_MODE));
}
}
public boolean render(XhtmlNode x, ResourceWrapper qr) throws UnsupportedEncodingException, IOException {
switch (context.getQuestionnaireMode()) {
case FORM: return renderTree(x, qr);
case LINKS: return renderLinks(x, qr);
// case LOGIC: return renderLogic(x, q);
// case DEFNS: return renderDefns(x, q);
case TREE: return renderTree(x, qr);
default:
throw new Error(context.formatPhrase(RenderingContext.QUEST_UNKNOWN_MODE));
}
}
public boolean renderTree(XhtmlNode x, ResourceWrapper qr) throws UnsupportedEncodingException, IOException {
public void renderTree(RenderingStatus status, XhtmlNode x, ResourceElement qr) throws UnsupportedEncodingException, IOException {
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context, context.getDestDir(), context.isInlineGraphics(), true);
TableModel model = gen.new TableModel("qtree="+qr.getId(), false);
model.setAlternating(true);
@ -76,63 +73,21 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.GENERAL_DEFINITION), context.formatPhrase(RenderingContext.QUEST_TIMES), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.QUEST_ANSWER), context.formatPhrase(RenderingContext.QUEST_TYPE_ITEM), null, 0));
boolean hasExt = false;
// first we add a root for the questionaire itself
Row row = addTreeRoot(gen, model.getRows(), qr);
List<BaseWrapper> items = qr.children("item");
for (BaseWrapper i : items) {
hasExt = renderTreeItem(gen, row.getSubRows(), qr, i) || hasExt;
List<ResourceElement> items = qr.children("item");
for (ResourceElement i : items) {
renderTreeItem(status, gen, row.getSubRows(), qr, i);
}
XhtmlNode xn = gen.generate(model, context.getLocalPrefix(), 1, null);
x.getChildNodes().add(xn);
return hasExt;
}
public boolean renderTree(XhtmlNode x, QuestionnaireResponse q) throws UnsupportedEncodingException, IOException {
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context, context.getDestDir(), context.isInlineGraphics(), true);
TableModel model = gen.new TableModel("qtree="+q.getId(), true);
model.setAlternating(true);
if (context.getRules() == GenerationRules.VALID_RESOURCE || context.isInlineGraphics()) {
model.setDocoImg(HierarchicalTableGenerator.help16AsData());
} else {
model.setDocoImg(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "help16.png"));
}
model.setDocoRef(context.getLink(KnownLinkType.SPEC)+"formats.html#table");
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.QUEST_LINKID), context.formatPhrase(RenderingContext.QUEST_LINK), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.QUEST_TEXT), context.formatPhrase(RenderingContext.QUEST_TEXTFOR), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.GENERAL_DEFINITION), context.formatPhrase(RenderingContext.QUEST_TIMES), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), context.formatPhrase(RenderingContext.QUEST_ANSWER), context.formatPhrase(RenderingContext.QUEST_TYPE_ITEM), null, 0));
boolean hasExt = false;
// first we add a root for the questionaire itself
Row row = addTreeRoot(gen, model.getRows(), q);
for (QuestionnaireResponseItemComponent i : q.getItem()) {
hasExt = renderTreeItem(gen, row.getSubRows(), q, i) || hasExt;
}
XhtmlNode xn = gen.generate(model, context.getLocalPrefix(), 1, null);
x.getChildNodes().add(xn);
return hasExt;
}
private Row addTreeRoot(HierarchicalTableGenerator gen, List<Row> rows, QuestionnaireResponse q) throws IOException {
private Row addTreeRoot(HierarchicalTableGenerator gen, List<Row> rows, ResourceElement qr) throws IOException {
Row r = gen.new Row();
rows.add(r);
r.setIcon("icon_q_root.gif", context.formatPhrase(RenderingContext.QUEST_RESP_ROOT));
r.getCells().add(gen.new Cell(null, null, q.getId(), null, null));
r.getCells().add(gen.new Cell(null, null, "", null, null));
r.getCells().add(gen.new Cell(null, null, context.formatPhrase(RenderingContext.QUEST_RESP), null, null));
r.getCells().add(gen.new Cell(null, null, "", null, null));
return r;
}
private Row addTreeRoot(HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper qr) throws IOException {
Row r = gen.new Row();
rows.add(r);
Base b = qr.get("questionnaire");
ResourceElement b = qr.child("questionnaire");
String ref = b == null ? null : b.primitiveValue();
Questionnaire q = context.getContext().fetchResource(Questionnaire.class, ref);
@ -152,18 +107,16 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
return r;
}
private boolean renderTreeItem(HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper q, BaseWrapper i) throws IOException {
private boolean renderTreeItem(RenderingStatus status, HierarchicalTableGenerator gen, List<Row> rows, ResourceElement qr, ResourceElement i) throws IOException {
Row r = gen.new Row();
rows.add(r);
boolean hasExt = false;
List<BaseWrapper> items = i.children("item");
List<BaseWrapper> answers = i.children("answer");
List<ResourceElement> items = i.children("item");
List<ResourceElement> answers = i.children("answer");
boolean hasItem = items != null && !items.isEmpty();
if (answers != null) {
for (BaseWrapper a : answers) {
for (ResourceElement a : answers) {
hasItem = a.has("item");
}
}
@ -172,40 +125,39 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
} else {
r.setIcon("icon-q-string.png", context.formatPhrase(RenderingContext.QUEST_ITEM));
}
String linkId = i.has("linkId") ? i.get("linkId").primitiveValue() : "??";
String text = i.has("text") ? i.get("text").primitiveValue() : "";
String linkId = i.has("linkId") ? i.primitiveValue("linkId") : "??";
String text = i.has("text") ? i.primitiveValue("text") : "";
r.getCells().add(gen.new Cell(null, context.getDefinitionsTarget() == null ? "" : context.getDefinitionsTarget()+"#item."+linkId, linkId, null, null));
r.getCells().add(gen.new Cell(null, null, text, null, null));
r.getCells().add(gen.new Cell(null, null, null, null, null));
if (answers == null || answers.size() == 0) {
r.getCells().add(gen.new Cell(null, null, null, null, null));
if (items != null) {
for (BaseWrapper si : items) {
renderTreeItem(gen, r.getSubRows(), q, si);
for (ResourceElement si : items) {
renderTreeItem(status, gen, r.getSubRows(), qr, si);
}
}
} else if (answers.size() == 1) {
BaseWrapper ans = answers.get(0);
renderAnswer(gen, q, r, ans);
ResourceElement ans = answers.get(0);
renderAnswer(status, gen, qr, r, ans);
} else {
r.getCells().add(gen.new Cell(null, null, null, null, null));
for (BaseWrapper ans : answers) {
for (ResourceElement ans : answers) {
Row ar = gen.new Row();
ar.setIcon("icon-q-string.png", "Item");
ar.getSubRows().add(ar);
ar.getCells().add(gen.new Cell(null, null, null, null, null));
ar.getCells().add(gen.new Cell(null, null, text, null, null));
ar.getCells().add(gen.new Cell(null, null, null, null, null));
renderAnswer(gen, q, ar, ans);
renderAnswer(status, gen, qr, ar, ans);
}
}
return hasExt;
}
public void renderAnswer(HierarchicalTableGenerator gen, ResourceWrapper q, Row r, BaseWrapper ans) throws UnsupportedEncodingException, IOException {
List<BaseWrapper> items;
Base b = ans.get("value[x]");
public void renderAnswer(RenderingStatus status, HierarchicalTableGenerator gen, ResourceElement qr, Row r, ResourceElement ans) throws UnsupportedEncodingException, IOException {
ResourceElement b = ans.child("value[x]");
if (b == null) {
r.getCells().add(gen.new Cell(null, null, "null!", null, null));
} else if (b.isPrimitive()) {
@ -216,12 +168,11 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
Piece p = gen.new Piece("span");
p.getChildren().add(x);
cell.addPiece(p);
render(x, (DataType) b);
renderDataType(status, x, b);
r.getCells().add(cell);
}
items = ans.children("item");
for (BaseWrapper si : items) {
renderTreeItem(gen, r.getSubRows(), q, si);
for (ResourceElement si : ans.children("item")) {
renderTreeItem(status, gen, r.getSubRows(), qr, si);
}
}
@ -324,7 +275,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
return false;
}
public boolean renderForm(XhtmlNode x, ResourceWrapper q) throws UnsupportedEncodingException, IOException {
public boolean renderForm(XhtmlNode x, ResourceElement q) throws UnsupportedEncodingException, IOException {
boolean hasExt = false;
XhtmlNode d = x.div();
d.tx(context.formatPhrase(RenderingContext.GENERAL_TODO));
@ -604,14 +555,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
// return "QuestionnaireResponse "+q.present();
// }
//
private boolean renderLinks(XhtmlNode x, QuestionnaireResponse q) {
x.para().tx(context.formatPhrase(RenderingContext.QUEST_TRY_QUEST));
XhtmlNode ul = x.ul();
ul.li().ah("http://todo.nlm.gov/path?mode=ig&src="+Utilities.pathURL(context.getLink(KnownLinkType.SELF), "package.tgz")+"&q="+q.getId()+".json").tx(context.formatPhrase(RenderingContext.QUEST_NLM));
return false;
}
private boolean renderLinks(XhtmlNode x, ResourceWrapper q) {
private boolean renderLinks(RenderingStatus status, XhtmlNode x, ResourceElement q) {
x.para().tx(context.formatPhrase(RenderingContext.QUEST_TRY_QUEST));
XhtmlNode ul = x.ul();
ul.li().ah("http://todo.nlm.gov/path?mode=ig&src="+Utilities.pathURL(context.getLink(KnownLinkType.SELF), "package.tgz")+"&q="+q.getId()+".json").tx(context.formatPhrase(RenderingContext.QUEST_NLM));
@ -874,14 +818,4 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
// }
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return context.formatPhrase(RenderingContext.GENERAL_TODO);
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return context.formatPhrase(RenderingContext.GENERAL_TODO);
}
}

View File

@ -51,6 +51,11 @@ public class Renderer {
return extensions;
}
public boolean isShowCodeDetails() {
// TODO Auto-generated method stub
return false;
}
}
protected RenderingContext context;
@ -234,12 +239,16 @@ public class Renderer {
return value.toString();
}
protected ResourceElement wrap(DataType type) {
return new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), type);
protected ResourceElement wrapNC(DataType type) {
return ResourceElement.forType(context.getContextUtilities(), context.getProfileUtilities(), type);
}
protected ResourceElement wrap(Resource resource) {
return new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), resource);
return ResourceElement.forResource(context.getContextUtilities(), context.getProfileUtilities(), resource);
}
protected ResourceElement wrapWC(ResourceElement resource, DataType type) {
return ResourceElement.forType(context.getContextUtilities(), context.getProfileUtilities(), resource, type);
}
}

View File

@ -19,11 +19,9 @@ import org.hl7.fhir.r5.model.Requirements.ConformanceExpectation;
import org.hl7.fhir.r5.model.Requirements.RequirementsStatementComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.UrlType;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
@ -45,48 +43,29 @@ public class RequirementsRenderer extends ResourceRenderer {
if (req.has("actor")) {
List<ResourceElement> actors = req.children("actor");
if (actors.size() == 1) {
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, actors.get(0).primitiveValue(), req);
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, actors.get(0).primitiveValue(), req.getResourceNative());
XhtmlNode p = x.para();
p.tx(context.formatPhrase(RenderingContext.REQ_ACTOR)+" ");
if (acd == null) {
p.code(actors.get(0).primitiveValue());
} else {
p.ah(acd.getWebPath()).tx(acd.present());
}
renderCanonical(status, p, ActorDefinition.class, actors.get(0));
} else {
x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_ACTOR)+" ");
XhtmlNode ul = x.ul();
for (ResourceElement a : actors) {
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, a.primitiveValue(), req);
if (acd == null) {
ul.li().code(a.primitiveValue());
} else {
ul.li().ah(acd.getWebPath()).tx(acd.present());
}
renderCanonical(status, ul.li(), ActorDefinition.class, a);
}
}
}
if (req.has("derivedFrom")) {
List<ResourceElement> list = req.children("derivedFrom");
if (list.size() == 1) {
Requirements reqd = context.getWorker().fetchResource(Requirements.class, list.get(0).primitiveValue(), req);
XhtmlNode p = x.para();
p.tx(context.formatPhrase(RenderingContext.REQ_DERIVE)+" ");
if (reqd == null) {
p.code(list.get(0).primitiveValue());
} else {
p.ah(reqd.getWebPath()).tx(reqd.present());
}
renderCanonical(status, p, Requirements.class, list.get(0));
} else {
x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_REQ)+" ");
XhtmlNode ul = x.ul();
for (ResourceElement a : list) {
Requirements reqd = context.getWorker().fetchResource(Requirements.class, a.primitiveValue(), req);
if (reqd == null) {
ul.li().code(a.primitiveValue());
} else {
ul.li().ah(reqd.getWebPath()).tx(reqd.present());
}
renderCanonical(status, ul.li(), Requirements.class, a);
}
}
}
@ -108,7 +87,7 @@ public class RequirementsRenderer extends ResourceRenderer {
for (ResourceElement stmt : req.children("statement")) {
XhtmlNode tr = tbl.tr();
String lbl = stmt.has("label") ? stmt.primitiveValue("label") : stmt..primitiveValue("key");
String lbl = stmt.has("label") ? stmt.primitiveValue("label") : stmt.primitiveValue("key");
XhtmlNode td = tr.td();
td.b().an(stmt.primitiveValue("key"));
td.tx(lbl);
@ -134,7 +113,7 @@ public class RequirementsRenderer extends ResourceRenderer {
String url = stmt.primitiveValue("derivedFrom");
String key = url.contains("#") ? url.substring(url.indexOf("#")+1) : "";
if (url.contains("#")) { url = url.substring(0, url.indexOf("#")); };
Requirements reqr = context.getWorker().fetchResource(Requirements.class, url, req);
Requirements reqr = context.getWorker().fetchResource(Requirements.class, url, req.getResourceNative());
if (reqr != null) {
RequirementsStatementComponent stmtr = reqr.findStatement(key);
if (stmtr != null) {
@ -156,7 +135,7 @@ public class RequirementsRenderer extends ResourceRenderer {
if (url.contains("#")) {
url = url.substring(0, url.indexOf("#"));
}
Resource r = context.getWorker().fetchResource(Resource.class, url, req);
Resource r = context.getWorker().fetchResource(Resource.class, url, req.getResourceNative());
if (r != null) {
String desc = getResourceDescription(r, null);
li.ah(c.primitiveValue()).tx(desc);
@ -190,10 +169,10 @@ public class RequirementsRenderer extends ResourceRenderer {
if (url.contains("#")) {
url = url.substring(0, url.indexOf("#"));
}
Resource r = context.getWorker().fetchResource(Resource.class, url, req);
Resource r = context.getWorker().fetchResource(Resource.class, url, req.getResourceNative());
ResourceWithReference t = null;
if (r == null && context.getResolver() != null) {
t = context.getResolver().resolve(context, url);
t = context.getResolver().resolve(context, url, null);
}
if (r != null) {
String desc = getResourceDescription(r, c.primitiveValue("display"));
@ -219,7 +198,7 @@ public class RequirementsRenderer extends ResourceRenderer {
if (!Utilities.noString(display)) {
return display;
}
return RendererFactory.factory(res.getResource(), context).display(res.getResource());
return RendererFactory.factory(res.getResource(), context).displayResource(res.getResource());
}
private String getResourceDescription(Resource res, String display) throws UnsupportedEncodingException, IOException {
@ -229,7 +208,7 @@ public class RequirementsRenderer extends ResourceRenderer {
if (res instanceof CanonicalResource) {
return ((CanonicalResource) res).present();
}
return RendererFactory.factory(res, context).display(res);
return RendererFactory.factory(res, context).displayResource(wrap(res));
}
public void describe(XhtmlNode x, Library lib) {

View File

@ -15,6 +15,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeableReference;
@ -29,11 +30,15 @@ import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceReferenceKind;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.renderers.utils.ResourceElement.ElementKind;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
@ -77,7 +82,13 @@ public abstract class ResourceRenderer extends DataRenderer {
/**
* given a resource, update it's narrative with the best rendering available.
*
* Explanation about native vs wrapped
* ResourceElement is a facade to either a org.hl7.fhir.r5.model Resource, or
* to a org.hl7.fhir.r5.elementModel (which might a resource of any version).
*
* Note that some resource renderers - only canonical ones - only render native
* resources, and not element model ones. These may be migrated in the future
* (only reason not to is the sheer size of the task, though performance might
* be a factor)
*
* @param r - the domain resource in question
*
@ -85,19 +96,6 @@ public abstract class ResourceRenderer extends DataRenderer {
* @throws EOperationOutcome
* @throws FHIRException
*/
public void renderResource(DomainResource r) throws IOException, FHIRException, EOperationOutcome {
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
RenderingStatus status = new RenderingStatus();
renderResource(status, x, r);
String an = r.fhirType()+"_"+r.getId();
if (context.isAddName()) {
if (!hasAnchorName(x, an)) {
injectAnchorName(x, an);
}
}
inject(r, x, status.getExtensions() ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
}
public void renderResource(ResourceElement r) throws IOException, FHIRException, EOperationOutcome {
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
RenderingStatus status = new RenderingStatus();
@ -146,9 +144,6 @@ public abstract class ResourceRenderer extends DataRenderer {
// these three are what the descendants of this class override
public abstract void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
renderResource(status, x, wrap(r));
}
public abstract String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException;
@ -173,33 +168,33 @@ public abstract class ResourceRenderer extends DataRenderer {
r.setNarrative(x, status.toCode(), multiLangMode, context.getLocale());
}
public void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
r.getText().setUserData("renderer.generated", true);
if (!r.hasText() || !r.getText().hasDiv()) {
r.setText(new Narrative());
r.getText().setStatus(status);
}
if (multiLangMode) {
if (!r.getText().hasDiv()) {
XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
div.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
r.getText().setDiv(div);
} else {
r.getText().getDiv().getChildNodes().removeIf(c -> !"div".equals(c.getName()) || !c.hasAttribute("xml:lang"));
}
markLanguage(x);
r.getText().getDiv().getChildNodes().add(x);
} else {
if (!x.hasAttribute("xmlns"))
x.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
if (r.hasLanguage()) {
// use both - see https://www.w3.org/TR/i18n-html-tech-lang/#langvalues
x.setAttribute("lang", r.getLanguage());
x.setAttribute("xml:lang", r.getLanguage());
}
r.getText().setDiv(x);
}
}
// public void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
// r.getText().setUserData("renderer.generated", true);
// if (!r.hasText() || !r.getText().hasDiv()) {
// r.setText(new Narrative());
// r.getText().setStatus(status);
// }
// if (multiLangMode) {
// if (!r.getText().hasDiv()) {
// XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
// div.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
// r.getText().setDiv(div);
// } else {
// r.getText().getDiv().getChildNodes().removeIf(c -> !"div".equals(c.getName()) || !c.hasAttribute("xml:lang"));
// }
// markLanguage(x);
// r.getText().getDiv().getChildNodes().add(x);
// } else {
// if (!x.hasAttribute("xmlns"))
// x.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
// if (r.hasLanguage()) {
// // use both - see https://www.w3.org/TR/i18n-html-tech-lang/#langvalues
// x.setAttribute("lang", r.getLanguage());
// x.setAttribute("xml:lang", r.getLanguage());
// }
// r.getText().setDiv(x);
// }
// }
public void markLanguage(XhtmlNode x) {
x.setAttribute("lang", context.getLocale().toString());
@ -209,94 +204,101 @@ public abstract class ResourceRenderer extends DataRenderer {
x.addTag(0, "hr");
}
public void renderCanonical(RenderingStatus status, ResourceElement resource, XhtmlNode x, ResourceElement canonical) throws UnsupportedEncodingException, IOException {
public <T extends Resource> void renderCanonical(RenderingStatus status, XhtmlNode x, Class<T> class_, ResourceElement canonical) throws UnsupportedEncodingException, IOException {
if (!renderPrimitiveWithNoValue(status, x, canonical)) {
renderCanonical(resource, x, canonical.primitiveValue(), true, resource);
CanonicalResource target = (CanonicalResource) context.getWorker().fetchResource(class_, canonical.primitiveValue(), canonical.getResourceNative());
if (target != null && target.hasWebPath()) {
if (canonical.primitiveValue().contains("|")) {
x.ah(target.getWebPath()).tx(target.present()+ context.formatPhrase(RenderingContext.RES_REND_VER) +target.getVersion()+")");
} else {
x.ah(target.getWebPath()).tx(target.present());
}
}
public void renderCanonical(ResourceElement res, XhtmlNode x, String url) throws UnsupportedEncodingException, IOException {
renderCanonical(res, x, url, true, res);
}
public void renderCanonical(ResourceElement rw, XhtmlNode x, String url, boolean allowLinks, ResourceElement src) throws UnsupportedEncodingException, IOException {
if (url == null) {
return;
}
Resource target = context.getWorker().fetchResource(Resource.class, url, src.getResource());
if (target == null || !(target instanceof CanonicalResource)) {
// we can't resolve it as a canonical in the context. We'll try to do a local resolution instead
ResourceWithReference rr = resolveReference(canonical);
if (rr != null) {
x.ah(rr.getReference()).tx(RendererFactory.factory(rr.getResource(), context).displayResource(rr.getResource()));
} else {
x.tx("??");
}
}
}
/**
* @param <T>
* @param status
* @param res
* @param x
* @param class_ - makes resolution faster, but can just be Resource.class
* @param canonical
* @throws UnsupportedEncodingException
* @throws IOException
*/
public <T extends Resource> void renderCanonical(RenderingStatus status, ResourceElement res, XhtmlNode x, Class<T> class_, CanonicalType canonical) throws UnsupportedEncodingException, IOException {
if (canonical == null || !canonical.hasPrimitiveValue()) {
return;
}
String url = canonical.asStringValue();
Resource target = context.getWorker().fetchResource(Resource.class, url, res.getResourceNative());
if (target == null || !(target instanceof CanonicalResource) || !target.hasWebPath()) {
x.code().tx(url);
} else {
CanonicalResource cr = (CanonicalResource) target;
if (url.contains("|")) {
if (target.hasWebPath()) {
x.ah(target.getWebPath()).tx(cr.present()+ context.formatPhrase(RenderingContext.RES_REND_VER) +cr.getVersion()+")");
} else {
url = url.substring(0, url.indexOf("|"));
x.code().tx(url);
x.tx(": "+cr.present()+ context.formatPhrase(RenderingContext.RES_REND_VER) +cr.getVersion()+")");
}
} else {
if (target.hasWebPath()) {
x.ah(target.getWebPath()).tx(cr.present());
} else {
x.code().tx(url);
x.tx(" ("+cr.present()+")");
}
}
}
}
public void renderReference(RenderingStatus status, ResourceElement res, XhtmlNode x, ResourceElement type) throws FHIRFormatError, DefinitionException, IOException {
if (type.fhirType().equals("Reference")) {
renderReference(status, res, x, type);
} else if (type.fhirType().equals("CodeableReference")) {
// todo: if (r.hasExtension(ToolingExtensions.EXT_TARGET_ID) || r.hasExtension(ToolingExtensions.EXT_TARGET_PATH)) {
@Override
public void renderReference(RenderingStatus status, XhtmlNode x, ResourceElement type) throws FHIRFormatError, DefinitionException, IOException {
ResourceElement display = null;
ResourceElement actual = null;
ResourceElement id = null;
if (type.fhirType().equals("CodeableReference")) {
if (type.has("reference")) {
renderReference(status, res, x, type, true);
type = type.child("reference");
} else {
renderDataType(status, x, type);
renderCodeableConcept(status, x, type.child("concept"));
return;
}
}
if (type.fhirType().equals("Reference")) {
display = type.child("display");
actual = type.child("reference");
id = type.child("identifier");
} else {
renderDataType(status, x, type);
actual = type;
}
if (actual != null && actual.hasPrimitiveValue()) {
ResourceWithReference rr = resolveReference(actual);
if (rr == null) {
String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : actual.primitiveValue();
x.ah(actual.primitiveValue()).tx(disp);
} else {
String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : RendererFactory.factory(rr.getResource(), context).displayResource(rr.getResource());
x.ah(rr.getReference()).tx(disp);
}
} else if (display != null && id != null) {
renderDataType(status, x, display);
x.tx(" (Identifier: ");
renderIdentifier(status, x, id);
x.tx(")");
} else if (display != null) {
renderDataType(status, x, display);
} else if (id != null) {
x.tx("Identifier: ");
renderIdentifier(status, x, id);
} else {
x.tx("??");
}
}
/*
* } else if (ew.fhirType().equals("Reference")) {
Reference r = (Reference) e;
if (r.getReference() != null && r.getReference().contains("#")) {
if (containedIds.contains(r.getReference().substring(1))) {
x.ah("#hc"+r.getReference().substring(1)).tx("See "+r.getReference());
} else {
// in this case, we render the resource in line
ResourceWrapper rw = null;
for (ResourceWrapper t : res.getContained()) {
if (r.getReference().substring(1).equals(t.getId())) {
rw = t;
}
}
if (rw == null) {
renderReference(res, x, r);
} else {
String ref = context.getResolver() != null ?context.getResolver().urlForContained(context, res.fhirType(), res.getId(), rw.fhirType(), rw.getId()) : null;
if (ref == null) {
x.an("hc"+rw.getId());
RenderingContext ctxtc = context.copy();
ctxtc.setAddGeneratedNarrativeHeader(false);
ctxtc.setContained(true);
ResourceRenderer rr = RendererFactory.factory(rw, ctxtc);
rr.setRcontext(new ResourceContext(rcontext, rw));
rr.render(parent.blockquote(), rw);
} else {
x.ah(ref).tx("See "+rw.fhirType());
}
}
}
} else {
renderReference(res, x, r);
}
*/
public void renderReference(Resource res, HierarchicalTableGenerator gen, List<Piece> pieces, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
public void renderReference(ResourceElement 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;
@ -305,7 +307,7 @@ public abstract class ResourceRenderer extends DataRenderer {
String link = null;
StringBuilder text = new StringBuilder();
if (r.hasReferenceElement() && allowLinks) {
tr = resolveReference(wrap(res), r.getReference());
tr = resolveReference(res, r.getReference());
if (!r.getReference().startsWith("#")) {
if (tr != null && tr.getReference() != null) {
@ -328,7 +330,7 @@ public abstract class ResourceRenderer extends DataRenderer {
if (!Utilities.noString(r.getReference())) {
text.append(r.getReference());
} else if (r.hasIdentifier()) {
text.append(displayIdentifier(wrap(r.getIdentifier())));
text.append(displayIdentifier(wrapWC(res, r.getIdentifier())));
} else {
text.append("??");
}
@ -371,6 +373,81 @@ public abstract class ResourceRenderer extends DataRenderer {
pieces.add(gen.new Piece(link,text.toString(), null));
}
public void renderReference(ResourceElement res, HierarchicalTableGenerator gen, List<Piece> pieces, ResourceElement r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
if (r == null) {
pieces.add(gen.new Piece(null, "null!", null));
return;
}
ResourceWithReference trt = null;
String link = null;
StringBuilder text = new StringBuilder();
if (r.has("reference") && allowLinks) {
trt = resolveReference(res, r.primitiveValue("reference"));
if (!r.primitiveValue("reference").startsWith("#")) {
if (trt != null && trt.getReference() != null) {
link = trt.getReference();
} else if (r.primitiveValue("reference").contains("?")) {
text.append(context.formatPhrase(RenderingContext.RES_REND_COND_REF)+" ");
} else {
link = r.primitiveValue("reference");
}
}
}
if (trt != null && trt.getReference() != null && trt.getReference().startsWith("#")) {
text.append(context.formatPhrase(RenderingContext.RES_REND_SEE_ON_THIS_PAGE)+" ");
}
// 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.has("display") ? r.primitiveValue("display") : null;
String name = trt != null && trt.getResource() != null ? getNameForResource(trt.getResource()) : null;
if (display == null && (trt == null || trt.getResource() == null)) {
if (!Utilities.noString(r.primitiveValue("reference"))) {
text.append(r.primitiveValue("reference"));
} else if (r.has("identifier")) {
text.append(displayIdentifier(r.child("identifier")));
} else {
text.append("??");
}
} else if (context.isTechnicalMode()) {
text.append(r.primitiveValue("reference"));
if (display != null) {
text.append(": "+display);
}
if ((trt == null || (trt.getReference() != null && !trt.getReference().startsWith("#"))) && name != null) {
text.append(" \""+name+"\"");
}
if (r.hasExtension(ToolingExtensions.EXT_TARGET_ID) || r.hasExtension(ToolingExtensions.EXT_TARGET_PATH)) {
text.append("(");
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_ID)) {
if (ex.has("value")) {
text.append(", ");
text.append("#"+ex.primitiveValue("value"));
}
}
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_PATH)) {
if (ex.has("value")) {
text.append(", ");
text.append("#"+ex.primitiveValue("value"));
}
}
text.append(")");
}
} else {
if (display != null) {
text.append(display);
} else if (name != null) {
text.append(name);
} else {
text.append(context.formatPhrase(RenderingContext.RES_REND_DESC));
}
}
if (trt != null && trt.getReference() != null && trt.getReference().startsWith("#")) {
text.append(")");
}
pieces.add(gen.new Piece(link,text.toString(), null));
}
protected String getNameForResource(ResourceElement resource) {
ResourceElement name = resource.firstChild("name");
if (name != null && !name.isEmpty()) {
@ -395,182 +472,187 @@ public abstract class ResourceRenderer extends DataRenderer {
}
}
public void renderReference(RenderingStatus status, ResourceElement rw, XhtmlNode x, ResourceElement r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
if (r == null) {
x.tx("null!");
return;
protected void renderUri(RenderingStatus status, ResourceElement resource, XhtmlNode x, UriType uri) throws FHIRFormatError, DefinitionException, IOException {
if (!renderPrimitiveWithNoValue(status, x, uri)) {
String v = uri.primitiveValue();
if (v.startsWith("mailto:")) {
x.ah(v).addText(v.substring(7));
} else {
ResourceWithReference rr = resolveReference(resource, uri.primitiveValue());
if (rr != null) {
x.ah(rr.getReference()).addText(RendererFactory.factory(rr.getResource(), context).displayResource(rr.getResource()));
} else {
Resource r = context.getContext().fetchResource(Resource.class, v);
if (r != null && r.getWebPath() != null) {
x.ah(r.getWebPath()).addText(RendererFactory.factory(r, context).displayResource(wrap(r)));
} else {
String url = context.getResolver() != null ? context.getResolver().resolveUri(context, v) : null;
if (url != null) {
x.ah(url).addText(v);
} else if (Utilities.isAbsoluteUrlLinkable(v) && !uri.fhirType().equals("id")) {
x.ah(v).addText(v);
} else {
x.addText(v);
}
}
}
}
}
}
XhtmlNode c = null;
ResourceWithReference tr = null;
boolean onPage = false;
String rref = r.primitiveValue("reference");
if (r.has("reference") && allowLinks) {
tr = resolveReference(rw, r.primitiveValue("reference"));
if (!rref.startsWith("#")) {
if (tr != null && tr.getReference() != null) {
if (tr.getReference().startsWith("#")) {
onPage = true;
if (context.getRules() == GenerationRules.IG_PUBLISHER || (tr != null && tr.getKind() != ResourceReferenceKind.BUNDLE)) {
c = x.ah("#hc"+tr.getReference().substring(1));
@Override
protected void renderUri(RenderingStatus status, XhtmlNode x, ResourceElement uri) throws FHIRFormatError, DefinitionException, IOException {
if (!renderPrimitiveWithNoValue(status, x, uri)) {
String v = uri.primitiveValue();
if (v.startsWith("mailto:")) {
x.ah(v).addText(v.substring(7));
} else {
c = x;
}
ResourceWithReference rr = resolveReference(uri);
if (rr != null) {
x.ah(rr.getReference()).addText(RendererFactory.factory(rr.getResource(), context).displayResource(rr.getResource()));
} else {
c = x.ah(tr.getReference());
}
} else if (rref.contains("?")) {
x.tx(context.formatPhrase(RenderingContext.RES_REND_COND_REF)+" ");
c = x.code("");
Resource r = context.getContext().fetchResource(Resource.class, v);
if (r != null && r.getWebPath() != null) {
x.ah(r.getWebPath()).addText(RendererFactory.factory(r, context).displayResource(wrap(r)));
} else {
c = x.ah(rref);
}
} else if ("#".equals(rref)) {
c = x.ah("#");
} else if (context.getRules() == GenerationRules.IG_PUBLISHER || (tr != null && tr.getKind() != ResourceReferenceKind.BUNDLE)) {
c = x.ah("#hc"+rref.substring(1));
onPage = true;
String url = context.getResolver() != null ? context.getResolver().resolveUri(context, v) : null;
if (url != null) {
x.ah(url).addText(v);
} else if (Utilities.isAbsoluteUrlLinkable(v) && !uri.fhirType().equals("id")) {
x.ah(v).addText(v);
} else {
c = x;
x.addText(v);
}
}
}
}
} else {
c = x.span(null, null);
}
if (onPage) {
c.tx(context.formatPhrase(RenderingContext.RES_REND_SEE_ON_THIS_PAGE)+" ");
}
// 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.has("display") ? r.primitiveValue("display") : null;
String name = tr != null && tr.getResource() != null ? getNameForResource(tr.getResource()) : null;
if (display == null && (tr == null || tr.getResource() == null)) {
if (!Utilities.noString(rref)) {
c.addText(rref);
} else if (r.has("identifier")) {
renderIdentifier(status, c, r.child("identifier"));
} else {
c.addText("??");
/**
* Eventually this will be retired if and when there's no more direct renderers
*
* @param <T>
*/
protected <T extends Resource> T findCanonical(Class<T> class_, UriType canonical, ResourceElement sourceOfReference) {
return context.getContext().fetchResource(class_, canonical.asStringValue(), sourceOfReference.getResourceNative());
}
} else if (context.isTechnicalMode()) {
c.addText(rref);
if (display != null) {
c.addText(": "+display);
}
if ((tr == null || (tr.getReference() != null && !tr.getReference().startsWith("#"))) && name != null) {
x.addText(" \""+name+"\"");
}
if (r.hasExtension(ToolingExtensions.EXT_TARGET_ID) || r.hasExtension(ToolingExtensions.EXT_TARGET_PATH)) {
x.addText("(");
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_ID)) {
if (ex.has("value")) {
x.sep(", ");
x.addText("#"+ex.primitiveValue("value"));
}
}
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_PATH)) {
if (ex.has("value")) {
x.sep(", ");
x.addText("/#"+ex.primitiveValue("value"));
}
}
x.addText(")");
}
} else {
if (display != null) {
c.addText(display);
} else if (name != null) {
c.addText(name);
} else {
c.tx(context.formatPhrase(RenderingContext.RES_REND_GEN_SUM)+" ");
if (tr != null) {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, rref.startsWith("#"), true);
}
}
}
}
//
// public void renderReference(ResourceWrapper rw, XhtmlNode x, BaseWrapper r) throws UnsupportedEncodingException, IOException {
// XhtmlNode c = x;
// ResourceWithReference tr = null;
// String v;
// if (r.has("reference")) {
// v = r.get("reference").primitiveValue();
// tr = resolveReference(rw, v);
//
// if (!v.startsWith("#")) {
// if (tr != null && tr.getReference() != null)
// c = x.ah(tr.getReference());
// else
// c = x.ah(v);
// }
// } else {
// v = "";
// }
// // what to display: if text is provided, then that. if the reference was resolved, then show the generated narrative
// if (r.has("display")) {
// c.addText(r.get("display").primitiveValue());
// if (tr != null && tr.getResource() != null) {
// c.tx(context.formatPhrase(RenderingContext.RES_REND_GEN_SUM)+" ");
// new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, v.startsWith("#"), false);
// }
// } else if (tr != null && tr.getResource() != null) {
// new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), v.startsWith("#"), v.startsWith("#"), false);
// } else {
// c.addText(v);
// }
// }
protected ResourceWithReference resolveReference(ResourceElement res, String url) {
if (url == null)
protected <T extends Resource> T findCanonical(Class<T> class_, String canonical, ResourceElement sourceOfReference) {
return context.getContext().fetchResource(class_, canonical, sourceOfReference.getResourceNative());
}
private ResourceWithReference resolveContained(ResourceElement resource, String url) {
ResourceElement container = findContainer(resource);
if (container == null) {
return null;
if (url.startsWith("#") && res != null) {
for (ResourceElement r : res.children("contained")) {
if (r.getId().equals(url.substring(1)))
return new ResourceWithReference(ResourceReferenceKind.CONTAINED, url, r);
} else if ("#".equals(url)) {
return new ResourceWithReference(ResourceReferenceKind.CONTAINER, "#hc"+container.getScopedId(), container);
} else {
String tid = url.substring(1);
for (ResourceElement c : container.children("contained")) {
if (tid.equals(c.getId())) {
return new ResourceWithReference(ResourceReferenceKind.CONTAINED, "#hc"+c.getScopedId(), c);
}
}
}
return null;
}
private ResourceElement findContainer(ResourceElement resource) {
ResourceElement container = resource;
while (container != null) {
if (container.isResource() && container.kind() != ElementKind.ContainedResource) {
break;
}
container = container.parent();
}
return container;
}
private ResourceWithReference resolveOutside(ResourceElement resource, String url, String version) {
ResourceElement container = findContainer(resource);
if (container != null) {
while (container != null) {
if (container.isResource() && container.fhirType().equals("Bundle")) {
ResourceWithReference rr = findInBundle(resource, url);
if (rr != null) {
return null;
}
}
container = container.parent();
}
}
// ok, we didn't find it in the current instance, so we go look elsewhere
if (context.getResolver() != null) {
ResourceWithReference rr = context.getResolver().resolve(context, url, version);
if (rr != null) {
return rr;
}
}
Resource r = context.getWorker().fetchResource(Resource.class, url, version);
if (r != null) {
return new ResourceWithReference(ResourceReferenceKind.EXTERNAL, r.getWebPath(), wrap(r));
}
return null;
}
private ResourceWithReference findInBundle(ResourceElement resource, String url) {
if (url.equals("Bundle/"+resource.getId())) {
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, "#"+resource.getScopedId(), resource);
}
for (ResourceElement entry : resource.children("entry")) {
if (entry.has("resource")) {
ResourceElement res = entry.child("resource");
if (entry.has("fullUrl")) {
String fu = entry.primitiveValue("fullUrl");
if (url.equals(fu)) {
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, "#"+res.getScopedId(), res);
}
}
if ("Bundle".equals(res.fhirType())) {
ResourceWithReference rr = findInBundle(res, url);
if (rr != null) {
return rr;
}
}
}
}
return null;
}
protected ResourceWithReference resolveReference(ResourceElement resource, String url) {
if (url == null) {
return null;
}
if (url.startsWith("#")) {
return resolveContained(resource, url);
} else {
String version = null;
if (url.contains("/_history/")) {
version = url.substring(url.indexOf("/_history/")+10);
url = url.substring(0, url.indexOf("/_history/"));
}
/*
if (rcontext != null) {
BundleEntryComponent bundleResource = rcontext.resolve(url);
if (bundleResource != null) {
String id = bundleResource.getResource().getId();
if (id == null) {
id = makeIdFromBundleEntry(bundleResource.getFullUrl());
return resolveOutside(resource, url, version);
}
String bundleUrl = "#" + bundleResource.getResource().getResourceType().name() + "_" + id;
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceElement(this.context.getContextUtilities(), bundleResource.getResource()));
}
org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url, version);
if (bundleElement != null) {
String bundleUrl = null;
Element br = bundleElement.getNamedChild("resource", false);
if (br.getChildValue("id") != null) {
if ("Bundle".equals(br.fhirType())) {
bundleUrl = "#";
protected ResourceWithReference resolveReference(ResourceElement reference) {
if (reference.fhirType().equals("CodeableReference")) {
if (reference.has("reference")) {
return resolveReference(reference.child("reference"));
} else {
bundleUrl = "#" + br.fhirType() + "_" + br.getChildValue("id");
}
} else {
bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl"));
}
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceElement(this.context.getContextUtilities(), br));
}
}
*/
Resource ae = getContext().getWorker().fetchResource(null, url, version);
if (ae != null)
return new ResourceWithReference(ResourceReferenceKind.EXTERNAL, url, new ResourceElement(this.context.getContextUtilities(), this.context.getProfileUtilities(), ae));
else if (context.getResolver() != null) {
return context.getResolver().resolve(context, url);
} else
return null;
}
} else if (reference.fhirType().equals("Reference")) {
return resolveReference(reference.getResourceWrapper(), reference.primitiveValue("reference"));
} else {
return resolveReference(reference.getResourceWrapper(), reference.primitiveValue());
}
}
protected String makeIdFromBundleEntry(String url) {
@ -587,10 +669,10 @@ public abstract class ResourceRenderer extends DataRenderer {
return url.replace(":", "").replace("/", "_");
}
protected void generateCopyright(XhtmlNode x, CanonicalResource cs) {
protected void generateCopyright(XhtmlNode x, ResourceElement cs) {
XhtmlNode p = x.para();
p.b().tx(getContext().formatPhrase(RenderingContext.RESOURCE_COPYRIGHT));
smartAddText(p, " " + cs.getCopyright());
smartAddText(p, " " + cs.primitiveValue("copyright"));
}
public String displayReference(Resource res, Reference r) throws UnsupportedEncodingException, IOException {
@ -700,7 +782,7 @@ public abstract class ResourceRenderer extends DataRenderer {
boolean first = true;
for (ResourceElement bw : items) {
if (first) first = false; else p.tx(", ");
renderCanonical(r, p, bw.primitiveValue());
renderCanonical(status, p, StructureDefinition.class, bw);
}
}
items = meta.children("tag");

View File

@ -7,6 +7,7 @@ import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Enumerations.SearchComparator;
@ -36,14 +37,14 @@ public class SearchParameterRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
render(status, x, (SearchParameter) r.getBase());
} else {
throw new Error("SearchParameterRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (SearchParameter) r);
}
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return canonicalTitle(r);

View File

@ -67,7 +67,6 @@ import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionMappingCompo
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.InternalMarkdownProcessor;
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.RenderStyle;
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.SourcedElementDefinition;
@ -112,12 +111,17 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (!r.isDirect()) {
throw new Error("StructureDefinitionRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (StructureDefinition) r);
StructureDefinition sd = (StructureDefinition) r.getBase();
if (context.getStructureMode() == StructureDefinitionRendererMode.DATA_DICT) {
renderDict(status, sd, sd.getDifferential().getElement(), x.table("dict"), false, GEN_MODE_DIFF, "", r);
} else {
x.getChildNodes().add(generateTable(status, context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false,
context.getLink(KnownLinkType.SPEC), "", sd.getKind() == StructureDefinitionKind.LOGICAL, false, null, false, context, "", r));
}
status.setExtensions(true);
}
@Override
@ -344,15 +348,6 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
public void render(RenderingStatus status, XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
if (context.getStructureMode() == StructureDefinitionRendererMode.DATA_DICT) {
renderDict(sd, sd.getDifferential().getElement(), x.table("dict"), false, GEN_MODE_DIFF, "");
} else {
x.getChildNodes().add(generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false,
context.getLink(KnownLinkType.SPEC), "", sd.getKind() == StructureDefinitionKind.LOGICAL, false, null, false, context, ""));
}
status.setExtensions(true);
}
public void describe(XhtmlNode x, StructureDefinition sd) {
x.tx(display(sd));
@ -362,18 +357,6 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return sd.present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
// private static final int AGG_NONE = 0;
// private static final int AGG_IND = 1;
// private static final int AGG_GR = 2;
@ -553,8 +536,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
public XhtmlNode generateTable(String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean mustSupport, RenderingContext rc, String anchorPrefix) throws IOException, FHIRException {
public XhtmlNode generateTable(RenderingStatus status, String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean mustSupport, RenderingContext rc, String anchorPrefix, ResourceElement res) throws IOException, FHIRException {
assert(diff != snapshot);// check it's ok to get rid of one of these
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context, imageFolder, inlineGraphics, true, defFile, anchorPrefix);
@ -588,7 +571,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
profiles.add(profile);
keyRows.clear();
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc, anchorPrefix, profile, columns);
genElement(status, defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc, anchorPrefix, profile, columns, res);
try {
return gen.generate(model, imagePath, 0, outputTracker);
} catch (org.hl7.fhir.exceptions.FHIRException e) {
@ -721,8 +704,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return model;
}
private Row genElement(String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions,
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc, String anchorPrefix, Resource srcSD, List<Column> columns) throws IOException, FHIRException {
private Row genElement(RenderingStatus status, String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions,
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc, String anchorPrefix, Resource srcSD, List<Column> columns, ResourceElement res) throws IOException, FHIRException {
Row originalRow = slicingRow;
StructureDefinition profile = profiles == null ? null : profiles.get(profiles.size()-1);
Row typesRow = null;
@ -822,7 +805,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
genElementObligations(gen, element, columns, row, corePath, profile);
break;
case SUMMARY:
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport, true, rc, children.size() > 0, defPath, anchorPrefix, all);
genElementCells(status, gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport, true, rc, children.size() > 0, defPath, anchorPrefix, all, res);
break;
}
if (element.hasSlicing()) {
@ -942,7 +925,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT))) {
slicer = genElement(defPath, gen, parent.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, slicer, mustSupport, rc, anchorPrefix, srcSD, columns);
slicer = genElement(status, defPath, gen, parent.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, slicer, mustSupport, rc, anchorPrefix, srcSD, columns, res);
}
}
}
@ -1083,9 +1066,9 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return left;
}
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
public List<Cell> genElementCells(RenderingStatus status, HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport, boolean allowSubRows, RenderingContext rc, boolean walksIntoThis, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws IOException {
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport, boolean allowSubRows, RenderingContext rc, boolean walksIntoThis, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements, ResourceElement resource) throws IOException {
List<Cell> res = new ArrayList<>();
Cell gc = gen.new Cell();
row.getCells().add(gc);
@ -1128,7 +1111,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (extDefn == null) {
res.add(genCardinality(gen, element, row, hasDef, used, null));
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(ProfileUtilities.UD_DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
} else {
String name = element.hasSliceName() ? element.getSliceName() : urltail(eurl);
nameCell.getPieces().get(0).setText(name);
@ -1141,7 +1124,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
else // if it's complex, we just call it nothing
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
res.add(addCell(row, gen.new Cell(null, null, "("+(context.formatPhrase(RenderingContext.STRUC_DEF_COMPLEX))+")", null, null)));
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport, allowSubRows, rc, inScopeElements));
res.add(generateDescription(status, gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
}
} else {
res.add(genCardinality(gen, element, row, hasDef, used, null));
@ -1149,7 +1132,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
res.add(addCell(row, gen.new Cell()));
else
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
}
}
} else if (element != null) {
@ -1158,7 +1141,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
else
res.add(addCell(row, gen.new Cell()));
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
}
return res;
}
@ -1315,15 +1298,15 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
&& element.getSlicing().getRules() != SlicingRules.CLOSED && element.getSlicing().getDiscriminator().size() == 1 && element.getSlicing().getDiscriminator().get(0).getPath().equals("url") && element.getSlicing().getDiscriminator().get(0).getType().equals(DiscriminatorType.VALUE);
}
public Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc) throws IOException, FHIRException {
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows, rc, new ArrayList<ElementDefinition>());
public Cell generateDescription(RenderingStatus status, HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc, ResourceElement res) throws IOException, FHIRException {
return generateDescription(status, gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows, rc, new ArrayList<ElementDefinition>(), res);
}
public Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc, List<ElementDefinition> inScopeElements) throws IOException, FHIRException {
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows, rc, inScopeElements);
public Cell generateDescription(RenderingStatus status, HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc, List<ElementDefinition> inScopeElements, ResourceElement res) throws IOException, FHIRException {
return generateDescription(status, gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows, rc, inScopeElements, res);
}
public Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc, List<ElementDefinition> inScopeElements) throws IOException, FHIRException {
public Cell generateDescription(RenderingStatus status, HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows, RenderingContext rc, List<ElementDefinition> inScopeElements, ResourceElement res) throws IOException, FHIRException {
Cell c = gen.new Cell();
row.getCells().add(c);
@ -1702,7 +1685,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (!definition.getPath().contains(".") && profile.hasExtension(ToolingExtensions.EXT_OBLIGATION_CORE, ToolingExtensions.EXT_OBLIGATION_TOOLS)) {
obr.seeObligations(profile.getExtensionsByUrl(ToolingExtensions.EXT_OBLIGATION_CORE, ToolingExtensions.EXT_OBLIGATION_TOOLS));
}
obr.renderTable(gen, c, inScopeElements);
obr.renderTable(status, res, gen, c, inScopeElements);
if (definition.hasMaxLength() && definition.getMaxLength()!=0) {
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
@ -3160,7 +3143,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return first ? null : x;
}
public XhtmlNode generateExtensionTable(String defFile, StructureDefinition ed, String imageFolder, boolean inlineGraphics, boolean full, String corePath, String imagePath, Set<String> outputTracker, RenderingContext rc, String defPath, String anchorPrefix) throws IOException, FHIRException {
public XhtmlNode generateExtensionTable(RenderingStatus status, String defFile, StructureDefinition ed, String imageFolder, boolean inlineGraphics, boolean full, String corePath, String imagePath, Set<String> outputTracker, RenderingContext rc, String defPath, String anchorPrefix, ResourceElement res) throws IOException, FHIRException {
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context, imageFolder, inlineGraphics, true, defPath, anchorPrefix);
TableModel model = gen.initNormalTable(corePath, false, true, ed.getId()+(full ? "f" : "n"), true, TableGenerationMode.XHTML);
@ -3198,7 +3181,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (!child.getPath().endsWith(".id")) {
List<StructureDefinition> sdl = new ArrayList<>();
sdl.add(ed);
genElement(defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false, rc, "", ed, null);
genElement(status, defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false, rc, "", ed, null, res);
}
} else if (deep) {
List<ElementDefinition> children = new ArrayList<ElementDefinition>();
@ -3222,7 +3205,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
r1.getCells().add(gen.new Cell(null, null, describeCardinality(c, null, new UnusedTracker()), null, null));
genTypes(gen, r1, ved, defFile, ed, corePath, imagePath, false, false);
r1.setIcon("icon_"+m+"extension_simple.png", context.formatPhrase(RenderingContext.TEXT_ICON_EXTENSION_SIMPLE));
generateDescription(gen, r1, c, null, true, corePath, corePath, ed, corePath, imagePath, false, false, false, ved, false, false, false, rc, new ArrayList<ElementDefinition>());
generateDescription(status, gen, r1, c, null, true, corePath, corePath, ed, corePath, imagePath, false, false, false, ved, false, false, false, rc, new ArrayList<ElementDefinition>(), res);
}
}
} else {
@ -3302,7 +3285,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return null;
}
public void renderDict(StructureDefinition sd, List<ElementDefinition> elements, XhtmlNode t, boolean incProfiledOut, int mode, String anchorPrefix) throws FHIRException, IOException {
public void renderDict(RenderingStatus status, StructureDefinition sd, List<ElementDefinition> elements, XhtmlNode t, boolean incProfiledOut, int mode, String anchorPrefix, ResourceElement res) throws FHIRException, IOException {
int i = 0;
Map<String, ElementDefinition> allAnchors = new HashMap<>();
List<ElementDefinition> excluded = new ArrayList<>();
@ -3335,7 +3318,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (isProfiledExtension(ec)) {
StructureDefinition extDefn = context.getContext().fetchResource(StructureDefinition.class, ec.getType().get(0).getProfile().get(0).getValue());
if (extDefn == null) {
generateElementInner(t, sd, ec, 1, null, compareElement, null, false, "", anchorPrefix, elements);
generateElementInner(status, t, sd, ec, 1, null, compareElement, null, false, "", anchorPrefix, elements, res);
} else {
ElementDefinition valueDefn = getExtensionValueDefinition(extDefn);
ElementDefinition compareValueDefn = null;
@ -3343,15 +3326,15 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
StructureDefinition compareExtDefn = context.getContext().fetchResource(StructureDefinition.class, compareElement.getType().get(0).getProfile().get(0).getValue());
compareValueDefn = getExtensionValueDefinition(extDefn);
} catch (Exception except) {}
generateElementInner(t, sd, ec, valueDefn == null || valueDefn.prohibited() ? 2 : 3, valueDefn, compareElement, compareValueDefn, false, "", anchorPrefix, elements);
generateElementInner(status, t, sd, ec, valueDefn == null || valueDefn.prohibited() ? 2 : 3, valueDefn, compareElement, compareValueDefn, false, "", anchorPrefix, elements, res);
// generateElementInner(b, extDefn, extDefn.getSnapshot().getElement().get(0), valueDefn == null ? 2 : 3, valueDefn);
}
} else {
while (!dstack.isEmpty() && !isParent(dstack.peek(), ec)) {
finish(t, sd, dstack.pop(), mode, "", anchorPrefix);
finish(status, t, sd, dstack.pop(), mode, "", anchorPrefix, res);
}
dstack.push(ec);
generateElementInner(t, sd, ec, mode, null, compareElement, null, false, "", anchorPrefix, elements);
generateElementInner(status, t, sd, ec, mode, null, compareElement, null, false, "", anchorPrefix, elements, res);
if (ec.hasSlicing()) {
generateSlicing(t, sd, ec, ec.getSlicing(), compareElement, mode, false);
}
@ -3361,12 +3344,12 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
i++;
}
while (!dstack.isEmpty()) {
finish(t, sd, dstack.pop(), mode, "", anchorPrefix);
finish(status, t, sd, dstack.pop(), mode, "", anchorPrefix, res);
}
finish(t, sd, null, mode, "", anchorPrefix);
finish(status, t, sd, null, mode, "", anchorPrefix, res);
}
private void finish(XhtmlNode t, StructureDefinition sd, ElementDefinition ed, int mode, String defPath, String anchorPrefix) throws FHIRException, IOException {
private void finish(RenderingStatus status, XhtmlNode t, StructureDefinition sd, ElementDefinition ed, int mode, String defPath, String anchorPrefix, ResourceElement res) throws FHIRException, IOException {
for (Base b : VersionComparisonAnnotation.getDeleted(ed == null ? sd : ed, "element")) {
ElementDefinition ec = (ElementDefinition) b;
@ -3376,7 +3359,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
sp.span("color: grey", null).tx("--");
sp.b().tx(". "+title);
generateElementInner(t, sd, ec, mode, null, null, null, true, defPath, anchorPrefix, new ArrayList<ElementDefinition>());
generateElementInner(status, t, sd, ec, mode, null, null, null, true, defPath, anchorPrefix, new ArrayList<ElementDefinition>(), res);
if (ec.hasSlicing()) {
generateSlicing(t, sd, ec, ec.getSlicing(), null, mode, true);
}
@ -3696,7 +3679,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return "color:DarkGray;text-decoration:line-through";
}
private void generateElementInner(XhtmlNode tbl, StructureDefinition sd, ElementDefinition d, int mode, ElementDefinition value, ElementDefinition compare, ElementDefinition compareValue, boolean strikethrough, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws FHIRException, IOException {
private void generateElementInner(RenderingStatus status, XhtmlNode tbl, StructureDefinition sd, ElementDefinition d, int mode, ElementDefinition value, ElementDefinition compare, ElementDefinition compareValue, boolean strikethrough, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements, ResourceElement res) throws FHIRException, IOException {
boolean root = !d.getPath().contains(".");
boolean slicedExtension = d.hasSliceName() && (d.getPath().endsWith(".extension") || d.getPath().endsWith(".modifierExtension"));
// int slicedExtensionMode = (mode == GEN_MODE_KEY) && slicedExtension ? GEN_MODE_SNAP : mode; // see ProfileUtilities.checkExtensionDoco / Task 3970
@ -3790,7 +3773,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
tableRow(tbl, context.formatPhrase(RenderingContext.STRUC_DEF_COMP_PROF), "http://hl7.org/fhir/extensions/StructureDefinition-structuredefinition-compliesWithProfile.html", strikethrough,
renderCanonicalListExt(context.formatPhrase(RenderingContext.STRUC_DEF_PROF_COMP)+" ", sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_COMPLIES_WITH_PROFILE)));
}
tableRow(tbl, context.formatPhrase(RenderingContext.GENERAL_OBLIG), null, strikethrough, describeObligations(d, root, sd, defPath, anchorPrefix, inScopeElements));
tableRow(tbl, context.formatPhrase(RenderingContext.GENERAL_OBLIG), null, strikethrough, describeObligations(status, d, root, sd, defPath, anchorPrefix, inScopeElements, res));
if (d.hasExtension(ToolingExtensions.EXT_EXTENSION_STYLE)) {
String es = d.getExtensionString(ToolingExtensions.EXT_EXTENSION_STYLE);
@ -3992,7 +3975,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
}
private XhtmlNode describeObligations(ElementDefinition d, boolean root, StructureDefinition sdx, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements) throws IOException {
private XhtmlNode describeObligations(RenderingStatus status, ElementDefinition d, boolean root, StructureDefinition sdx, String defPath, String anchorPrefix, List<ElementDefinition> inScopeElements, ResourceElement res) throws IOException {
XhtmlNode ret = new XhtmlNode(NodeType.Element, "div");
ObligationsRenderer obr = new ObligationsRenderer(corePath, sdx, d.getPath(), context, hostMd, this);
obr.seeObligations(d.getExtensionsByUrl(ToolingExtensions.EXT_OBLIGATION_CORE, ToolingExtensions.EXT_OBLIGATION_TOOLS));
@ -4022,7 +4005,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
if (obr.hasObligations()) {
XhtmlNode tbl = ret.table("grid");
obr.renderTable(tbl.getChildNodes(), true, defPath, anchorPrefix, inScopeElements);
obr.renderTable(status, res, tbl.getChildNodes(), true, defPath, anchorPrefix, inScopeElements);
if (tbl.isEmpty()) {
ret.remove(tbl);
}

View File

@ -12,6 +12,7 @@ import java.util.Set;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
@ -53,14 +54,14 @@ public class StructureMapRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (r.isDirect()) {
renderMap(status, x, (StructureMap) r.getBase());
} else {
throw new Error("StructureMapRenderer only renders native resources directly");
}
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
renderMap(status, x, (StructureMap) r);
}
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return canonicalTitle(r);

View File

@ -4,24 +4,12 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Enumerations.SearchComparator;
import org.hl7.fhir.r5.model.Enumerations.SearchModifierCode;
import org.hl7.fhir.r5.model.Library;
import org.hl7.fhir.r5.model.MarkdownType;
import org.hl7.fhir.r5.model.Requirements;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.SubscriptionTopic;
import org.hl7.fhir.r5.model.SubscriptionTopic.InteractionTrigger;
import org.hl7.fhir.r5.model.SubscriptionTopic.SubscriptionTopicCanFilterByComponent;
import org.hl7.fhir.r5.model.SubscriptionTopic.SubscriptionTopicEventTriggerComponent;
import org.hl7.fhir.r5.model.SubscriptionTopic.SubscriptionTopicNotificationShapeComponent;
import org.hl7.fhir.r5.model.SubscriptionTopic.SubscriptionTopicResourceTriggerComponent;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class SubscriptionTopicRenderer extends ResourceRenderer {
@ -30,142 +18,119 @@ public class SubscriptionTopicRenderer extends ResourceRenderer {
super(context);
}
public SubscriptionTopicRenderer(RenderingContext context, ResourceContext rcontext) {
super(context, rcontext);
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return canonicalTitle(r);
}
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (SubscriptionTopic) dr);
}
public boolean render(XhtmlNode x, SubscriptionTopic st) throws FHIRFormatError, DefinitionException, IOException {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement st) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (context.isHeader()) {
XhtmlNode h = x.h2();
h.addText(st.hasTitle() ? st.getTitle() : st.getName());
addMarkdown(x, st.getDescription());
if (st.hasCopyright())
h.addText(st.has("title") ? st.primitiveValue("title") : st.primitiveValue("name"));
addMarkdown(x, st.primitiveValue("description"));
if (st.has("copyright")) {
generateCopyright(x, st);
}
if (st.hasResourceTrigger()) {
TableData td = new TableData(context.formatPhrase(RenderingContext.SUB_TOPIC_RES_TRIG));
for (SubscriptionTopicResourceTriggerComponent rt : st.getResourceTrigger()) {
TableRowData tr = td.addRow();
if (rt.hasResource()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.getResourceElement());
}
for (Enumeration<InteractionTrigger> t : rt.getSupportedInteraction()) {
if (st.has("resourceTrigger")) {
TableData td = new TableData(context.formatPhrase(RenderingContext.SUB_TOPIC_RES_TRIG));
for (ResourceElement rt : st.children("resourceTrigger")) {
TableRowData tr = td.addRow();
if (rt.has("resource")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.child("resource"));
}
for (ResourceElement t : rt.children("supportedInteraction")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_INT), t);
}
if (rt.hasQueryCriteria()) {
if (rt.has("queryCriteria")) {
StringBuilder md = new StringBuilder();
if (rt.getQueryCriteria().hasPrevious()) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_PREV, rt.getQueryCriteria().getPrevious()+"\r\n")+" ");
ResourceElement qc = rt.child("queryCriteria");
if (qc.has("previous")) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_PREV, qc.primitiveValue("previous")+"\r\n")+" ");
}
if (rt.getQueryCriteria().hasResultForCreate()) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_CREATE, rt.getQueryCriteria().getResultForCreate()+"\r\n")+" ");
if (qc.has("resultForCreate")) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_CREATE, qc.primitiveValue("resultForCreate")+"\r\n")+" ");
}
if (rt.getQueryCriteria().hasCurrent()) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_CREATE, rt.getQueryCriteria().getCurrent()+"\r\n")+" ");
if (qc.has("current")) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_CREATE, qc.primitiveValue("current")+"\r\n")+" ");
}
if (rt.getQueryCriteria().hasPrevious()) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_DELETE, rt.getQueryCriteria().getResultForDelete()+"\r\n")+" ");
if (qc.has("previous")) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_DELETE, qc.primitiveValue("resultForDelete")+"\r\n")+" ");
}
if (rt.getQueryCriteria().hasRequireBoth()) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_REQ, rt.getQueryCriteria().getRequireBoth()+"\r\n")+" ");
if (qc.has("requireBoth")) {
md.append(context.formatPhrase(RenderingContext.SUB_TOPIC_REQ, qc.primitiveValue("requireBoth")+"\r\n")+" ");
}
tr.value(context.formatPhrase(RenderingContext.GENERAL_CRIT), new MarkdownType(md.toString()));
tr.value(context.formatPhrase(RenderingContext.GENERAL_CRIT), wrapNC(new MarkdownType(md.toString())));
}
if (rt.hasFhirPathCriteriaElement()) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FHIR_PATH), rt.getFhirPathCriteriaElement());
if (rt.has("fhirPathCriteria")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FHIR_PATH), rt.child("fhirPathCriteria"));
}
if (rt.hasDescription()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_DESC), rt.getDescriptionElement());
if (rt.has("description")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_DESC), rt.child("description"));
}
}
renderTable(td, x);
renderTable(status, td, x);
}
if (st.hasEventTrigger()) {
if (st.has("eventTrigger")) {
TableData td = new TableData("Event Triggers");
for (SubscriptionTopicEventTriggerComponent rt : st.getEventTrigger()) {
for (ResourceElement rt : st.children("eventTrigger")) {
TableRowData tr = td.addRow();
if (rt.hasResource()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.getResourceElement());
if (rt.has("resource")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.child("resource"));
}
if (rt.hasEvent()) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_EVENT), rt.getEvent());
if (rt.has("event(")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_EVENT), rt.child("event"));
}
if (rt.hasDescription()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_DESC), rt.getDescriptionElement());
if (rt.has("description")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_DESC), rt.child("description"));
}
}
renderTable(td, x);
renderTable(status, td, x);
}
if (st.hasCanFilterBy()) {
if (st.has("canFilterBy")) {
TableData td = new TableData("Can Filter By");
for (SubscriptionTopicCanFilterByComponent rt : st.getCanFilterBy()) {
for (ResourceElement rt : st.children("canFilterBy")) {
TableRowData tr = td.addRow();
if (rt.hasResource()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.getResourceElement());
if (rt.has("resource")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.child("resource"));
}
if (rt.hasFilterParameter()) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FILT_PAR), rt.getFilterParameterElement());
if (rt.has("filterParameter")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FILT_PAR), rt.child("filterParameter"));
}
if (rt.hasFilterDefinition()) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FILT_DEF), rt.getFilterDefinitionElement());
if (rt.has("filterDefinition")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_FILT_DEF), rt.child("filterDefinition"));
}
for (Enumeration<SearchComparator> t : rt.getComparator()) {
for (ResourceElement t : rt.children("comparator")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_COMPARATORS), t);
}
for (Enumeration<SearchModifierCode> t : rt.getModifier()) {
for (ResourceElement t : rt.children("modifier")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_MODIFIERS), t);
}
}
renderTable(td, x);
renderTable(status, td, x);
}
if (st.hasNotificationShape()) {
if (st.has("notificationShape")) {
TableData td = new TableData("Notification Shapes");
for (SubscriptionTopicNotificationShapeComponent rt : st.getNotificationShape()) {
for (ResourceElement rt : st.children("notificationShape")) {
TableRowData tr = td.addRow();
if (rt.hasResource()) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.getResourceElement());
if (rt.has("resource")) {
tr.value(context.formatPhrase(RenderingContext.GENERAL_RESOURCE), rt.child("resource"));
}
for (StringType t : rt.getInclude()) {
for (ResourceElement t : rt.children("include")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_INCL), t);
}
for (StringType t : rt.getRevInclude()) {
for (ResourceElement t : rt.children("revInclude")) {
tr.value(context.formatPhrase(RenderingContext.SUB_TOPIC_REV_INCL), t);
}
}
renderTable(td, x);
renderTable(status, td, x);
}
return false;
}
public void describe(XhtmlNode x, Library lib) {
x.tx(display(lib));
}
public String display(Library lib) {
return lib.present();
}
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return ((Library) r).present();
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -2,61 +2,46 @@ package org.hl7.fhir.r5.renderers;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.CodeableReference;
import org.hl7.fhir.r5.model.ContactDetail;
import org.hl7.fhir.r5.model.ContactPoint;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.TestPlan;
import org.hl7.fhir.r5.model.TestPlan.TestCaseDependencyComponent;
import org.hl7.fhir.r5.model.TestPlan.TestPlanDependencyComponent;
import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseAssertionComponent;
import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseComponent;
import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseTestDataComponent;
import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseTestRunComponent;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class TestPlanRenderer extends ResourceRenderer {
public TestPlanRenderer(RenderingContext context) {
super(context);
}
public TestPlanRenderer(RenderingContext context, ResourceContext rcontext) {
super(context, rcontext);
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
return canonicalTitle(r);
}
@Override
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
return render(x, (TestPlan) r);
}
public boolean render(XhtmlNode x, TestPlan tp) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement tp) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
XhtmlNode p = null;
if (!tp.getContact().isEmpty()) {
if (tp.has("contact")) {
p = x.para();
p.b().tx(context.formatPhrase(RenderingContext.GENERAL_CONTACT));
p.tx(" (");
boolean firsti = true;
for (ContactDetail ci : tp.getContact()) {
for (ResourceElement ci : tp.children("contact")) {
if (firsti)
firsti = false;
else
p.tx(", ");
if (ci.hasName())
p.addText(ci.getName() + ": ");
if (ci.has("name"))
p.addText(ci.primitiveValue("name") + ": ");
boolean first = true;
for (ContactPoint c : ci.getTelecom()) {
for (ResourceElement c : ci.children("telecom")) {
if (first)
first = false;
else
@ -67,259 +52,257 @@ public class TestPlanRenderer extends ResourceRenderer {
p.tx(")");
}
if (tp.hasCategory()) {
if (tp.has("category")) {
p = x.para();
p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_CATEGORY)+" ");
boolean first = true;
for (CodeableConcept cc : tp.getCategory()) {
for (ResourceElement cc : tp.children("category")) {
if (first)
first = false;
else
p.tx(", ");
renderCodeableConcept(p, cc, false);
renderCodeableConcept(status, p, cc);
}
}
if (tp.hasScope()) {
if (tp.getScope().size() == 1) {
if (tp.has("scope")) {
List<ResourceElement> scopes = tp.children("scope");
if (scopes.size() == 1) {
p = x.para();
p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPE)+" ");
renderReference(tp, p, tp.getScopeFirstRep());
renderReference(status, p, scopes.get(0));
} else {
x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPES));
XhtmlNode ul = x.ul();
for (Reference ref : tp.getScope()) {
renderReference(tp, ul.li(), ref);
for (ResourceElement ref : scopes) {
renderReference(status, ul.li(), ref);
}
}
}
if (tp.hasDependency()) {
if (tp.getDependency().size() == 1) {
if (tp.has("dependency")) {
List<ResourceElement> deps = tp.children("dependency");
if (deps.size() == 1) {
ResourceElement dep = deps.get(0);
p = x.para();
p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_DEP)+" ");
XhtmlNode t = x.table("grid");
XhtmlNode tr = t.tr();
if (!Utilities.noString(tp.getDependencyFirstRep().getDescription())) {
addMarkdown(tr.td(), tp.getDependencyFirstRep().getDescription());
if (!Utilities.noString(dep.primitiveValue("description"))) {
addMarkdown(tr.td(), dep.primitiveValue("description"));
}
tr = t.tr();
renderReference(tp, tr.td(), tp.getDependencyFirstRep().getPredecessor());
renderReference(status, tr.td(), dep.child("predecessor"));
} else {
x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_DEPEN));
XhtmlNode ul = x.ul();
XhtmlNode li = null;
for (TestPlanDependencyComponent d : tp.getDependency()) {
for (ResourceElement d : deps) {
li = ul.li();
if (!Utilities.noString(d.getDescription())) {
addMarkdown(li, d.getDescription());
if (!Utilities.noString(d.primitiveValue("description"))) {
addMarkdown(li, d.primitiveValue("description"));
}
else {
li.addText(context.formatPhrase(RenderingContext.TEST_PLAN_DESC));
}
if (d.hasPredecessor()) {
if (d.has("predecessor")) {
XhtmlNode liul = li.ul();
XhtmlNode liulli = liul.li();
renderReference(tp, liulli, d.getPredecessor());
renderReference(status, liulli, d.child("predecessor"));
}
}
}
}
if (tp.hasExitCriteria()) {
addMarkdown(x, tp.getExitCriteria());
if (tp.has("exitCriteria")) {
addMarkdown(x, tp.primitiveValue("exitCriteria"));
}
if (tp.hasTestCase()) {
for (TestPlanTestCaseComponent tc : tp.getTestCase()) {
x.h2().addText(tc.hasSequence() ? formatPhrase(RenderingContext.TEST_PLAN_CASE) : formatPhrase(RenderingContext.TEST_PLAN_CASE_SEQ, tc.getSequence()));
for (ResourceElement tc : tp.children("testCase")) {
x.h2().addText(tc.has("sequence") ? formatPhrase(RenderingContext.TEST_PLAN_CASE) : formatPhrase(RenderingContext.TEST_PLAN_CASE_SEQ, tc.primitiveValue("sequence")));
if (tc.hasScope()) {
if (tc.getScope().size() == 1) {
if (tc.has("scope")) {
List<ResourceElement> scopes = tc.children("scope");
if (scopes.size() == 1) {
p = x.para();
p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPE)+" ");
renderReference(tp, p, tc.getScopeFirstRep());
renderReference(status, p, scopes.get(0));
} else {
x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPES));
XhtmlNode ul = x.ul();
for (Reference ref : tc.getScope()) {
renderReference(tp, ul.li(), ref);
for (ResourceElement ref : scopes) {
renderReference(status, ul.li(), ref);
}
}
}
if (tc.hasDependency()) {
if (tc.getDependency().size() == 1) {
if (tc.has("dependency")) {
List<ResourceElement> deps = tc.children("dependency");
if (deps.size() == 1) {
ResourceElement dep = deps.get(0);
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DEP));
XhtmlNode t = x.table("grid");
XhtmlNode tr = t.tr();
if (!Utilities.noString(tc.getDependencyFirstRep().getDescription())) {
addMarkdown(tr.td(), tc.getDependencyFirstRep().getDescription());
if (!Utilities.noString(dep.primitiveValue("description"))) {
addMarkdown(tr.td(), dep.primitiveValue("description"));
}
tr = t.tr();
renderReference(tp, tr.td(), tc.getDependencyFirstRep().getPredecessor());
renderReference(status, tr.td(), dep.child("predecessor"));
} else {
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DEPEN));
XhtmlNode ul = x.ul();
XhtmlNode li = null;
for (TestCaseDependencyComponent d : tc.getDependency()) {
for (ResourceElement d : deps) {
li = ul.li();
if (!Utilities.noString(d.getDescription())) {
addMarkdown(li, d.getDescription());
if (!Utilities.noString(d.primitiveValue("description"))) {
addMarkdown(li, d.primitiveValue("description"));
}
else {
li.addText(context.formatPhrase(RenderingContext.TEST_PLAN_DESC));
}
if (d.hasPredecessor()) {
if (d.has("predecessor")) {
XhtmlNode liul = li.ul();
XhtmlNode liulli = liul.li();
renderReference(tp, liulli, d.getPredecessor());
renderReference(status, liulli, d.child("predecessor"));
}
}
}
}
if (tc.hasTestRun()) {
if (tc.getTestRun().size() == 1) {
if (tc.has("testRun")) {
List<ResourceElement> runs = tc.children("testRun");
if (runs.size() == 1) {
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_RUN));
renderTestRun(x, tp, tc.getTestRunFirstRep());
renderTestRun(status, x, tp, runs.get(0));
}
else {
int count = 0;
for (TestPlanTestCaseTestRunComponent trun : tc.getTestRun()) {
for (ResourceElement trun : runs) {
count++;
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_TEST_RUN, count)+" ");
renderTestRun(x, tp, trun);
renderTestRun(status, x, tp, trun);
}
}
}
if (tc.hasTestData()) {
if (tc.getTestData().size() == 1) {
if (tc.has("testData")) {
List<ResourceElement> dl = tc.children("testData");
if (dl.size() == 1) {
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DATA));
renderTestData(x, tp, tc.getTestDataFirstRep());
renderTestData(status, x, tp, dl.get(0));
}
else {
int count = 0;
for (TestPlanTestCaseTestDataComponent tdata : tc.getTestData()) {
for (ResourceElement tdata : dl) {
count++;
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_TEST_DATA, count)+" ");
renderTestData(x, tp, tdata);
renderTestData(status, x, tp, tdata);
}
}
}
if (tc.hasAssertion()) {
if (tc.getAssertion().size() == 1) {
if (tc.has("assertion")) {
List<ResourceElement> al = tc.children("assertion");
if (al.size() == 1) {
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_ASS));
renderAssertion(x, tp, tc.getAssertionFirstRep());
renderAssertion(status, x, tp, al.get(0));
}
else {
int count = 0;
for (TestPlanTestCaseAssertionComponent as : tc.getAssertion()) {
for (ResourceElement as : al) {
count++;
x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_ASSERTION, count)+" ");
renderAssertion(x, tp, as);
renderAssertion(status, x, tp, as);
}
}
}
}
}
return false;
}
private void renderTestRun(XhtmlNode x, TestPlan tp, TestPlanTestCaseTestRunComponent trun) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
private void renderTestRun(RenderingStatus status, XhtmlNode x, ResourceElement tp, ResourceElement trun) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (trun.hasNarrative()) {
addMarkdown(x, trun.getNarrative());
addMarkdown(x, trun.primitiveValue("narrative"));
}
if (trun.hasScript()) {
if (trun.has("script")) {
ResourceElement script = trun.child("script");
XhtmlNode t = x.table("grid");
XhtmlNode tr = t.tr();
tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_LANG));
tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_SOURCE));
tr = t.tr();
if (trun.getScript().hasLanguage()) {
renderCodeableConcept(tr.td(), trun.getScript().getLanguage(), false);
}
else {
if (script.has("language")) {
renderCodeableConcept(status, tr.td(), script.child("language"));
} else {
tr.td().addText("??");
}
if (trun.getScript().hasSourceReference()) {
renderReference(tp, tr.td(), trun.getScript().getSourceReference());
}
else if(trun.getScript().hasSourceStringType()) {
tr.td().addText(trun.getScript().getSourceStringType().asStringValue());
}
else {
if (script.has("source")) {
renderDataType(status, tr.td(), script.child("script"));
} else {
tr.td().addText("??");
}
}
}
private void renderTestData(XhtmlNode x, TestPlan tp, TestPlanTestCaseTestDataComponent tdata) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
private void renderTestData(RenderingStatus status, XhtmlNode x, ResourceElement tp, ResourceElement tdata) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
XhtmlNode t = x.table("grid");
XhtmlNode tr = t.tr();
tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_TYPE));
tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_CONTENT));
tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_SOURCE));
tr = t.tr();
if (tdata.hasType()) {
renderCoding(tr.td(), tdata.getType());
if (tdata.has("type")) {
renderCoding(status, tr.td(), tdata.child("type"));
}
else {
tr.td().addText("??");
}
if (tdata.hasContent()) {
renderReference(tp, tr.td(), tdata.getContent());
if (tdata.has("content")) {
renderReference(status, tr.td(), tdata.child("content"));
}
else {
tr.td().addText("??");
}
if (tdata.hasSourceReference()) {
renderReference(tp, tr.td(), tdata.getSourceReference());
}
else if(tdata.hasSourceStringType()) {
tr.td().addText(tdata.getSourceStringType().asStringValue());
}
else {
if (tdata.has("source")) {
renderDataType(status, tr.td(), tdata.child("source"));
} else {
tr.td().addText("??");
}
}
private void renderAssertion(XhtmlNode x, TestPlan tp, TestPlanTestCaseAssertionComponent as) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
private void renderAssertion(RenderingStatus status, XhtmlNode x, ResourceElement tp, ResourceElement as) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
XhtmlNode t = x.table("grid");
XhtmlNode tr = t.tr();
tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_TYPE));
tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_CONTENT));
tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_RESULT));
tr = t.tr();
if (as.hasType()) {
if (as.has("type")) {
XhtmlNode td = tr.td();
XhtmlNode ul = td.ul();
for (CodeableConcept cc : as.getType()) {
renderCodeableConcept(ul.li(), cc, false);
for (ResourceElement cc : as.children("type")) {
renderCodeableConcept(status, ul.li(), cc);
}
}
else {
tr.td().addText("??");
}
if (as.hasObject()) {
if (as.has("object")) {
XhtmlNode td = tr.td();
XhtmlNode ul = td.ul();
for (CodeableReference cr : as.getObject()) {
renderCodeableReference(ul.li(), cr, false);
for (ResourceElement cr : as.children("object")) {
renderCodeableReference(status, ul.li(), cr);
}
}
else {
tr.td().addText("??");
}
if (as.hasResult()) {
if (as.has("result")) {
XhtmlNode td = tr.td();
XhtmlNode ul = td.ul();
for (CodeableReference cr : as.getResult()) {
renderCodeableReference(ul.li(), cr, false);
for (ResourceElement cr : as.children("result")) {
renderCodeableReference(status, ul.li(), cr);
}
}
else {
@ -327,17 +310,4 @@ public class TestPlanRenderer extends ResourceRenderer {
}
}
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return null;
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -18,6 +18,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.comparison.VersionComparisonAnnotation;
import org.hl7.fhir.r5.model.ActorDefinition;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
@ -73,13 +74,20 @@ public class ValueSetRenderer extends TerminologyRenderer {
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (!r.isDirect()) {
throw new Error("ValueSetRenderer only renders native resources directly");
}
ValueSet vs = (ValueSet) r.getBase();
List<UsedConceptMap> maps = findReleventMaps(vs);
@Override
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
render(status, x, (ValueSet) r, false);
if (vs.hasExpansion()) {
// for now, we just accept an expansion if there is one
generateExpansion(status, r, x, vs, false, maps);
} else {
generateComposition(status, r, x, vs, false, maps);
}
}
@Override
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
@ -94,14 +102,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
public void render(RenderingStatus status, XhtmlNode x, ValueSet vs, boolean header) throws FHIRFormatError, DefinitionException, IOException {
List<UsedConceptMap> maps = findReleventMaps(vs);
if (vs.hasExpansion()) {
// for now, we just accept an expansion if there is one
generateExpansion(status, x, vs, header, maps);
} else {
generateComposition(status, x, vs, header, maps);
}
}
public void describe(XhtmlNode x, ValueSet vs) {
@ -177,7 +178,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
return vs.hasUrl() && source != null && vs.getUrl().equals(source.primitiveValue());
}
private void generateExpansion(RenderingStatus status, XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
private void generateExpansion(RenderingStatus status, ResourceElement res, XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
List<String> langs = new ArrayList<String>();
Map<String, String> designations = new HashMap<>(); // map of url = description, where url is the designation code. Designations that are for languages won't make it into this list
Map<String, String> properties = new HashMap<>(); // map of url = description, where url is the designation code. Designations that are for languages won't make it into this list
@ -188,7 +189,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
if (IsNotFixedExpansion(vs))
addMarkdown(x, vs.getDescription());
if (vs.hasCopyright())
generateCopyright(x, vs);
generateCopyright(x, res);
}
boolean hasFragment = generateContentModeNotices(x, vs.getExpansion(), vs);
generateVersionNotice(x, vs.getExpansion(), vs);
@ -934,7 +935,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
// a.addText(code);
}
private void generateComposition(RenderingStatus status, XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRException, IOException {
private void generateComposition(RenderingStatus status, ResourceElement res, XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRException, IOException {
List<String> langs = new ArrayList<String>();
Map<String, String> designations = new HashMap<>(); // map of url = description, where url is the designation code. Designations that are for languages won't make it into this list
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
@ -950,7 +951,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
h.addText(vs.present());
addMarkdown(x, vs.getDescription());
if (vs.hasCopyrightElement())
generateCopyright(x, vs);
generateCopyright(x, res);
}
int index = 0;
if (vs.getCompose().getInclude().size() == 1 && vs.getCompose().getExclude().size() == 0 && !VersionComparisonAnnotation.hasDeleted(vs.getCompose(), "include", "exclude")) {

View File

@ -32,7 +32,7 @@ public class CanonicalSpreadsheetGenerator extends SpreadsheetGenerator {
}
addMetadataRow(sheet, "URL", cr.getUrl());
for (Identifier id : cr.getIdentifier()) {
addMetadataRow(sheet, "Identifier", dr.display(id));
addMetadataRow(sheet, "Identifier", dr.displayDataType(id));
}
addMetadataRow(sheet, "Version", cr.getVersion());
addMetadataRow(sheet, "Name", cr.getName());
@ -42,10 +42,10 @@ public class CanonicalSpreadsheetGenerator extends SpreadsheetGenerator {
addMetadataRow(sheet, "Date", cr.getDateElement().asStringValue());
addMetadataRow(sheet, "Publisher", cr.getPublisher());
for (ContactDetail c : cr.getContact()) {
addMetadataRow(sheet, "Contact", dr.display(c));
addMetadataRow(sheet, "Contact", dr.displayDataType(c));
}
for (CodeableConcept j : cr.getJurisdiction()) {
addMetadataRow(sheet, "Jurisdiction", dr.display(j));
addMetadataRow(sheet, "Jurisdiction", dr.displayDataType(j));
}
addMetadataRow(sheet, "Description", cr.getDescription());

View File

@ -106,7 +106,7 @@ public class CodeSystemSpreadsheetGenerator extends CanonicalSpreadsheetGenerato
Sheet sheet = makeSheet("Expansion Parameters");
addHeaders(sheet, "Parameter", "Value");
for (ValueSetExpansionParameterComponent p : params) {
addRow(sheet, p.getName(), dr.display(p.getValue()));
addRow(sheet, p.getName(), dr.displayDataType(p.getValue()));
}
}

View File

@ -135,7 +135,7 @@ public class StructureDefinitionSpreadsheetGenerator extends CanonicalSpreadshee
private void addStructureDefinitionMetadata(Sheet sheet, StructureDefinition sd) {
for (Coding k : sd.getKeyword()) {
addMetadataRow(sheet, "Keyword", dr.display(k));
addMetadataRow(sheet, "Keyword", dr.displayDataType(k));
}
addMetadataRow(sheet, "FHIR Version", sd.getFhirVersionElement().asStringValue());
addMetadataRow(sheet, "Kind", sd.getKindElement().asStringValue());

View File

@ -59,7 +59,7 @@ public class ValueSetSpreadsheetGenerator extends CanonicalSpreadsheetGenerator
Sheet sheet = makeSheet("Expansion Parameters");
addHeaders(sheet, "Parameter", "Value");
for (ValueSetExpansionParameterComponent p : params) {
addRow(sheet, p.getName(), dr.display(p.getValue()));
addRow(sheet, p.getName(), dr.displayDataType(p.getValue()));
}
}

View File

@ -6,7 +6,6 @@ import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceReferenceKind;
import org.w3c.dom.Element;
@ -14,10 +13,7 @@ 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);
ResourceWithReference resolve(RenderingContext context, String url, String version);
/**
* returns the correct literal URL for the specified logical uri
@ -187,7 +183,7 @@ public class Resolver {
*/
public enum ResourceReferenceKind {
CONTAINED, BUNDLE, EXTERNAL, UNKNOWN
CONTAINED, BUNDLE, EXTERNAL, UNKNOWN, CONTAINER
}

View File

@ -18,6 +18,7 @@ import org.hl7.fhir.r5.model.Narrative;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -71,62 +72,104 @@ public class ResourceElement {
private List<ResourceElement> children;
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, Resource resource) {
this.contextUtils = contextUtils;
this.profileUtils = profileUtils;
this.parent = null;
this.name = null;
this.index = -1;
this.kind = ElementKind.IndependentResource;
this.element = resource;
this.classDefinition = profileUtils.getContext().fetchTypeDefinition(resource.fhirType());
this.propertyDefinition = this.classDefinition.getSnapshot().getElementFirstRep();
// -- Constructors ------------------------------------------------------------------
private ResourceElement() {
// TODO Auto-generated constructor stub
}
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, DataType type) {
this.contextUtils = parent.contextUtils;
this.profileUtils = parent.profileUtils;
this.parent = null;
this.name = null;
this.index = -1;
this.kind = null;
this.element = type;
this.classDefinition = profileUtils.getContext().fetchTypeDefinition(type.fhirType());
this.propertyDefinition = this.classDefinition.getSnapshot().getElementFirstRep();
public static ResourceElement forResource(ContextUtilities contextUtils, ProfileUtilities profileUtils, Resource resource) {
ResourceElement self = new ResourceElement();
self.contextUtils = contextUtils;
self.profileUtils = profileUtils;
self.parent = null;
self.name = null;
self.index = -1;
self.kind = ElementKind.IndependentResource;
self.element = resource;
self.classDefinition = profileUtils.getContext().fetchTypeDefinition(resource.fhirType());
self.propertyDefinition = self.classDefinition.getSnapshot().getElementFirstRep();
return self;
}
public ResourceElement(ResourceElement parent, String name, int index, ElementKind kind, Base element, StructureDefinition classDefinition, ElementDefinition propertyDefinition) {
this.contextUtils = contextUtils;
this.profileUtils = profileUtils;
this.parent = parent;
this.name = name;
this.index = index;
this.kind = kind;
this.element = element;
this.classDefinition = classDefinition;
this.propertyDefinition = propertyDefinition;
public static ResourceElement forResource(ContextUtilities contextUtils, ProfileUtilities profileUtils, Element resource) {
ResourceElement self = new ResourceElement();
self.contextUtils = contextUtils;
self.profileUtils = profileUtils;
self.parent = null;
self.name = null;
self.index = -1;
self.kind = ElementKind.IndependentResource;
self.model = resource;
return self;
}
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, Element resource) {
this.contextUtils = contextUtils;
this.profileUtils = profileUtils;
this.parent = null;
this.name = null;
this.index = -1;
this.kind = ElementKind.IndependentResource;
this.model = resource;
public static ResourceElement forType(ContextUtilities contextUtils, ProfileUtilities profileUtils, Element resource) {
ResourceElement self = new ResourceElement();
self.contextUtils = contextUtils;
self.profileUtils = profileUtils;
self.parent = null;
self.name = null;
self.index = -1;
self.kind = ElementKind.DataType;
self.model = resource;
return self;
}
public ResourceElement(ResourceElement parent, String name, int index, ElementKind kind, Element em) {
this.contextUtils = parent.contextUtils;
this.profileUtils = parent.profileUtils;
this.parent = parent;
this.name = name;
this.index = index;
this.kind = kind;
this.model = em;
this.classDefinition = em.getProperty().getStructure();
this.propertyDefinition = em.getProperty().getDefinition();
public static ResourceElement forType(ContextUtilities contextUtils, ProfileUtilities profileUtils, DataType type) {
ResourceElement self = new ResourceElement();
self.contextUtils = contextUtils;
self.profileUtils = profileUtils;
self.parent = null;
self.name = null;
self.index = -1;
self.kind = null;
self.element = type;
self.classDefinition = profileUtils.getContext().fetchTypeDefinition(type.fhirType());
self.propertyDefinition = self.classDefinition.getSnapshot().getElementFirstRep();
return self;
}
public static ResourceElement forType(ContextUtilities contextUtils, ProfileUtilities profileUtils, ResourceElement parent, DataType type) {
ResourceElement self = new ResourceElement();
self.contextUtils = contextUtils;
self.profileUtils = profileUtils;
self.parent = parent;
self.name = null;
self.index = -1;
self.kind = null;
self.element = type;
self.classDefinition = profileUtils.getContext().fetchTypeDefinition(type.fhirType());
self.propertyDefinition = self.classDefinition.getSnapshot().getElementFirstRep();
return self;
}
private ResourceElement makeChild(String name, int index, ElementKind kind, Element em) {
ResourceElement self = new ResourceElement();
self.contextUtils = this.contextUtils;
self.profileUtils = this.profileUtils;
self.parent = this;
self.name = name;
self.index = index;
self.kind = kind;
self.model = em;
self.classDefinition = em.getProperty().getStructure();
self.propertyDefinition = em.getProperty().getDefinition();
return self;
}
private ResourceElement makeChild(String name, int index, ElementKind kind, Base element, StructureDefinition classDefinition, ElementDefinition propertyDefinition) {
ResourceElement self = new ResourceElement();
self.contextUtils = this.contextUtils;
self.profileUtils = this.profileUtils;
self.parent = this;
self.name = name;
self.index = index;
self.kind = kind;
self.element = element;
self.classDefinition = classDefinition;
self.propertyDefinition = propertyDefinition;
return self;
}
public String fhirVersion() {
@ -136,6 +179,7 @@ public class ResourceElement {
return model.getFHIRPublicationVersion().toCode();
}
}
public String path() {
if (parent == null) {
return fhirType();
@ -239,7 +283,7 @@ public class ResourceElement {
String name = child.getProperty().isChoice() ? child.getProperty().getName() : child.getName();
int index = child.isList() ? child.getIndex() : -1;
ElementKind kind = determineModelKind(child);
children.add(new ResourceElement(this, name, index, kind, child));
children.add(makeChild(name, index, kind, child));
}
}
@ -288,11 +332,11 @@ public class ResourceElement {
}
}
if (ed != null) {
children.add(new ResourceElement(this, name, index, kind, v, childDefs.getSource(), ed));
children.add(makeChild(name, index, kind, v, childDefs.getSource(), ed));
} else {
StructureDefinition sd = profileUtils.getContext().fetchTypeDefinition(v.fhirType());
ElementDefinition ted = sd.getSnapshot().getElementFirstRep();
children.add(new ResourceElement(this, name, index, kind, v, sd, ted));
children.add(makeChild(name, index, kind, v, sd, ted));
}
i++;
}
@ -627,6 +671,25 @@ public class ResourceElement {
}
public boolean matches(ResourceElement b) {
if (isEmpty() || b.isEmpty()) {
return isEmpty() && b.isEmpty();
} else {
if (hasPrimitiveValue() || b.hasPrimitiveValue()) {
if (!hasPrimitiveValue() || !b.hasPrimitiveValue() || !primitiveValue().equals(b.primitiveValue())) {
return false;
}
}
if (children().size() != b.children().size()) {
return false;
} else {
for (int i = 0; i < children().size(); i++) {
if (!children().get(i).matches(b.children().get(i))) {
return false;
}
}
return true;
}
}
}
public String extensionString(String url) {
@ -645,8 +708,17 @@ public class ResourceElement {
return !isPrimitive() || !hasPrimitiveValue();
}
public Resource getResource() {
return element == null ? null : (Resource) element;
public Resource getResourceNative() {
ResourceElement focus = getResourceWrapper();
return (Resource) focus.element;
}
public ResourceElement getResourceWrapper() {
ResourceElement focus = this;
while (focus != null && !focus.isResource()) {
focus = focus.parent;
}
return focus;
}
public ResourceElement firstChild(String name) {
@ -682,10 +754,61 @@ public class ResourceElement {
return propertyDefinition;
}
public List<XhtmlNode> getXhtml() {
public XhtmlNode getXhtml() {
if (element != null) {
return element.getXhtml();
} else {
return model.getXhtml();
}
}
public Base getBase() {
if (element != null) {
return element;
} else {
return model;
}
}
public boolean isDirect() {
return element != null;
}
public String getScopedId() {
if (!isResource()) {
return null;
} else {
String res = getId();
if (parent != null) {
res = parent.getResourceWrapper().getScopedId()+"/"+getId();
}
return res;
}
}
public ResourceElement parent() {
return parent;
}
public ResourceElement getContained(String id) {
if (isResource()) {
List<ResourceElement> contained = children("contained");
for (ResourceElement e : contained) {
if (id.equals(e.getId())) {
return e;
}
}
}
return null;
}
public String getWebPath() {
if (isResource()) {
if (element != null) {
return ((Resource) element).getWebPath();
}
}
return null;
}

View File

@ -25,8 +25,8 @@ import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.RendererFactory;
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
@ -256,7 +256,7 @@ public class NarrativeGenerationTests {
source = (Resource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + ".xml"));
}
XhtmlNode x = RendererFactory.factory(source, rc).build(source);
XhtmlNode x = RendererFactory.factory(source, rc).build(ResourceElement.forResource(rc.getContextUtilities(), rc.getProfileUtilities(), source));
String expected = TextFile.streamToString(TestingUtilities.loadTestResourceStream("r5", "narrative", "output", test.getId() + ".html"));
String actual = HEADER+new XhtmlComposer(true, test.pretty).compose(x)+FOOTER;
String expectedFileName = CompareUtilities.tempFile("narrative", test.getId() + ".expected.html");
@ -268,7 +268,7 @@ public class NarrativeGenerationTests {
if (test.isMeta()) {
org.hl7.fhir.r5.elementmodel.Element e = Manager.parseSingle(context, TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + ".xml"), FhirFormat.XML);
x = RendererFactory.factory(source, rc).render(new ElementWrappers.ResourceWrapperMetaElement(rc, e));
x = RendererFactory.factory(source, rc).build(ResourceElement.forResource(rc.getContextUtilities(), rc.getProfileUtilities(), e));
expected = TextFile.streamToString(TestingUtilities.loadTestResourceStream("r5", "narrative", "output", test.getId() + "-meta.html"));
actual = HEADER+new XhtmlComposer(true, true).compose(x)+FOOTER;

View File

@ -14,8 +14,10 @@ import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.renderers.DataRenderer;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.RendererFactory;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.test.utils.CompareUtilities;
@ -48,7 +50,7 @@ public class NarrativeGeneratorTests {
private void process(InputStream stream) throws FileNotFoundException, IOException, XmlPullParserException, EOperationOutcome, FHIRException {
XmlParser p = new XmlParser();
DomainResource r = (DomainResource) p.parse(stream);
RendererFactory.factory(r, rc).render(r);
RendererFactory.factory(r, rc).renderResource(ResourceElement.forResource(rc.getContextUtilities(), rc.getProfileUtilities(), r));
FileOutputStream s = ManagedFileAccess.outStream(TestingUtilities.tempFile("gen", "gen.xml"));
new XmlParser().compose(s, r, true);
s.close();
@ -71,11 +73,11 @@ public class NarrativeGeneratorTests {
rc.setMode(mode);
DateTimeType dt = new DateTimeType(src);
String actual = new DataRenderer(rc).display(dt);
String actual = new DataRenderer(rc).displayDataType(ResourceElement.forType(rc.getContextUtilities(), rc.getProfileUtilities(), dt));
Assert.assertTrue("Actual = "+actual+", expected one of "+Utilities.toString(expected), Utilities.existsInList(actual, expected));
XhtmlNode node = new XhtmlNode(NodeType.Element, "p");
new DataRenderer(rc).render(node, dt);
new DataRenderer(rc).renderDataType(new RenderingStatus(), node, ResourceElement.forType(rc.getContextUtilities(), rc.getProfileUtilities(), dt));
actual = new XhtmlComposer(true, false).compose(node);
Assert.assertTrue(actual.startsWith("<p>"));
Assert.assertTrue(actual.endsWith("</p>"));

View File

@ -23,6 +23,7 @@ import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.RendererFactory;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.test.utils.CompareUtilities;
@ -37,7 +38,7 @@ public class ResourceRoundTripTests {
public void test() throws IOException, FHIRException, EOperationOutcome {
DomainResource res = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"));
RenderingContext rc = new RenderingContext(TestingUtilities.getSharedWorkerContext(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER, GenerationRules.VALID_RESOURCE);
RendererFactory.factory(res, rc).render(res);
RendererFactory.factory(res, rc).renderResource(ResourceElement.forResource(rc.getContextUtilities(), rc.getProfileUtilities(), res));
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"), ManagedFileAccess.outStream(TestingUtilities.tempFile("gen", "unicode.xml")));
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(TestingUtilities.tempFile("gen", "unicode.out.xml")), res);
}

View File

@ -40,6 +40,7 @@ import org.hl7.fhir.r5.renderers.RendererFactory;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
@ -572,7 +573,7 @@ public class SnapShotGenerationTests {
RenderingContext rc = new RenderingContext(TestingUtilities.getSharedWorkerContext(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER, GenerationRules.VALID_RESOURCE);
rc.setDestDir(Utilities.path("[tmp]", "snapshot"));
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), null, new TestPKP()));
RendererFactory.factory(output, rc).render(output);
RendererFactory.factory(output, rc).renderResource(ResourceElement.forResource(rc.getContextUtilities(), rc.getProfileUtilities(), output));
}
if (!fail) {
test.output = output;

View File

@ -7500,6 +7500,28 @@ v: {
"system" : "http://loinc.org",
"version" : "2.77",
"server" : "http://tx-dev.fhir.org/r4",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://loinc.org",
"code" : "100066-0"
}, "url": "http://hl7.org/fhir/test/ValueSet/package-version-test-valueset--0", "version": "0.2.0", "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Specular microscopy panel",
"code" : "100066-0",
"system" : "http://loinc.org",
"version" : "2.77",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"

View File

@ -494,6 +494,23 @@ v: {
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
"valueUrl" : "http://tx-dev.fhir.org/r4"
}],
"severity" : "information",
"code" : "invalid",
"details" : {
"coding" : [{
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
"code" : "code-rule"
}],
"text" : "The code '1419004' is valid but is not active"
},
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
@ -833,6 +850,23 @@ v: {
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
"valueUrl" : "http://tx-dev.fhir.org/r4"
}],
"severity" : "information",
"code" : "invalid",
"details" : {
"coding" : [{
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
"code" : "code-rule"
}],
"text" : "The code '324252006' is valid but is not active"
},
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
@ -1075,6 +1109,23 @@ v: {
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
"valueUrl" : "http://tx-dev.fhir.org/r4"
}],
"severity" : "information",
"code" : "invalid",
"details" : {
"coding" : [{
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
"code" : "code-rule"
}],
"text" : "The code '602001' is valid but is not active"
},
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
@ -1639,6 +1690,23 @@ v: {
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
"valueUrl" : "http://tx-dev.fhir.org/r4"
}],
"severity" : "information",
"code" : "invalid",
"details" : {
"coding" : [{
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
"code" : "code-rule"
}],
"text" : "The code '1419004' is valid but is not active"
},
"location" : ["CodeableConcept.coding[0].code"],
"expression" : ["CodeableConcept.coding[0].code"]
},
{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
@ -8305,6 +8373,51 @@ v: {
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
"server" : "http://tx-dev.fhir.org/r4",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "252829002"
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Corneal specular microscopy",
"code" : "252829002",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "252829002"
}, "url": "http://hl7.org/fhir/test/ValueSet/package-version-test-valueset--0", "version": "0.1.0", "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Corneal specular microscopy",
"code" : "252829002",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"