Merge pull request #1376 from hapifhir/ExampleScenarioRendering
Example scenario rendering
This commit is contained in:
commit
f9ef847a35
|
@ -166,7 +166,13 @@
|
|||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.plantuml</groupId>
|
||||
<artifactId>plantuml-mit</artifactId>
|
||||
<version>1.2023.9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -0,0 +1,481 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.FileFormatOption;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.model.*;
|
||||
import org.hl7.fhir.r5.model.ExampleScenario.*;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlDocument;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import net.sourceforge.plantuml.SourceStringReader;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExampleScenarioRenderer extends TerminologyRenderer {
|
||||
|
||||
public ExampleScenarioRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Resource scen) throws IOException {
|
||||
return render(x, (ExampleScenario) scen);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, ExampleScenario scen) throws FHIRException {
|
||||
try {
|
||||
switch (context.getScenarioMode()) {
|
||||
case ACTORS:
|
||||
return renderActors(x, scen);
|
||||
case INSTANCES:
|
||||
return renderInstances(x, scen);
|
||||
case PROCESSES:
|
||||
return renderProcesses(x, scen);
|
||||
default:
|
||||
throw new FHIRException("Unknown ExampleScenario Renderer Mode " + context.getScenarioMode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException("Error rendering ExampleScenario " + scen.getUrl(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public String renderDiagram(ExampleScenario scen) throws IOException {
|
||||
String plantUml = toPlantUml(scen);
|
||||
SourceStringReader reader = new SourceStringReader(plantUml);
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
reader.outputImage(os, new FileFormatOption(FileFormat.SVG));
|
||||
os.close();
|
||||
|
||||
final String svg = new String(os.toByteArray(), Charset.forName("UTF-8"));
|
||||
return svg;
|
||||
}
|
||||
|
||||
protected String toPlantUml(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>();
|
||||
|
||||
for (ExampleScenarioActorComponent actor: scen.getActor()) {
|
||||
String actorType = actor.getType().equals(Enumerations.ExampleScenarioActorType.PERSON) ? "actor" : "participant";
|
||||
actorKeys.put(actor.getKey(), escapeKey(actor.getKey()));
|
||||
plantUml += actorType + " \"" + creolLink(actor.getTitle(), "#a_" + actor.getKey(), actor.getDescription()) + "\" as " + actorKeys.get(actor.getKey()) + "\r\n";
|
||||
}
|
||||
plantUml += "\r\n";
|
||||
|
||||
int processNum = 1;
|
||||
for (ExampleScenarioProcessComponent process: scen.getProcess()) {
|
||||
plantUml += toPlantUml(process, Integer.toString(processNum), scen, actorKeys);
|
||||
processNum++;
|
||||
}
|
||||
plantUml += "@enduml";
|
||||
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
private String escapeKey(String origKey) {
|
||||
char[] chars = origKey.toCharArray();
|
||||
for (int i=0; i<chars.length; i++) {
|
||||
char c = chars[i];
|
||||
if (!((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='@' || c=='.'))
|
||||
chars[i] = '_';
|
||||
}
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
protected String toPlantUml(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>();
|
||||
for (ExampleScenarioActorComponent actor : scen.getActor()) {
|
||||
actorsActive.put(actor.getKey(), Boolean.FALSE);
|
||||
}
|
||||
int stepCount = 1;
|
||||
for (ExampleScenarioProcessStepComponent step: process.getStep()) {
|
||||
plantUml += toPlantUml(step, stepPrefix(prefix, step, stepCount), scen, actorsActive, actorKeys);
|
||||
stepCount++;
|
||||
}
|
||||
|
||||
plantUml += "end\r\n\r\n";
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
protected String toPlantUml(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(scen, n, step.getWorkflow());
|
||||
XhtmlNode ref = n.getChildNodes().get(0);
|
||||
plantUml += noteOver(scen.getActor(), "Step " + trimPrefix(prefix) + " - See scenario\n" + creolLink(ref.getContent(), ref.getAttribute("href")));
|
||||
} else if (step.hasProcess())
|
||||
plantUml += toPlantUml(step.getProcess(), prefix, scen, actorKeys);
|
||||
else {
|
||||
// Operation
|
||||
plantUml += toPlantUml(step.getOperation(), prefix, scen, actorsActive, actorKeys);
|
||||
}
|
||||
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
protected String toPlantUml(ExampleScenarioProcessStepOperationComponent op, String prefix, ExampleScenario scen, Map<String,Boolean> actorsActive, Map<String, String> actorKeys) {
|
||||
StringBuilder plantUml = new StringBuilder();
|
||||
plantUml.append(handleActivation(op.getInitiator(), op.getInitiatorActive(), actorsActive, actorKeys));
|
||||
plantUml.append(handleActivation(op.getReceiver(), op.getReceiverActive(), actorsActive, actorKeys));
|
||||
plantUml.append(actorKeys.get(op.getInitiator()) + " -> " + actorKeys.get(op.getReceiver()) + ": ");
|
||||
plantUml.append(creolLink(op.getTitle(), "#s_" + prefix, op.getDescription()));
|
||||
if (op.hasRequest()) {
|
||||
plantUml.append(" (" + creolLink("payload", linkForInstance(op.getRequest())) + ")\r\n");
|
||||
}
|
||||
if (op.hasResponse()) {
|
||||
plantUml.append("activate " + actorKeys.get(op.getReceiver()) + "\r\n");
|
||||
plantUml.append(actorKeys.get(op.getReceiver()) + " --> " + actorKeys.get(op.getInitiator()) + ": ");
|
||||
plantUml.append(creolLink("response", "#s_" + prefix, op.getDescription()));
|
||||
plantUml.append(" (" + creolLink("payload", linkForInstance(op.getRequest())) + ")\r\n");
|
||||
plantUml.append("deactivate " + actorKeys.get(op.getReceiver()) + "\r\n");
|
||||
}
|
||||
plantUml.append(handleDeactivation(op.getInitiator(), op.getInitiatorActive(), actorsActive, actorKeys));
|
||||
plantUml.append(handleDeactivation(op.getReceiver(), op.getReceiverActive(), actorsActive, actorKeys));
|
||||
|
||||
return plantUml.toString();
|
||||
}
|
||||
|
||||
private String handleActivation(String actorId, boolean active, Map<String,Boolean> actorsActive, Map<String, String> actorKeys) {
|
||||
String plantUml = "";
|
||||
Boolean actorWasActive = actorsActive.get(actorId);
|
||||
if (active && !actorWasActive) {
|
||||
plantUml += "activate " + actorKeys.get(actorId) + "\r\n";
|
||||
}
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
private String handleDeactivation(String actorId, boolean active, Map<String,Boolean> actorsActive, Map<String, String> actorKeys) {
|
||||
String plantUml = "";
|
||||
Boolean actorWasActive = actorsActive.get(actorId);
|
||||
if (!active && actorWasActive) {
|
||||
plantUml += "deactivate " + actorKeys.get(actorId) + "\r\n";
|
||||
}
|
||||
if (active != actorWasActive) {
|
||||
actorsActive.remove(actorId);
|
||||
actorsActive.put(actorId, Boolean.valueOf(active));
|
||||
}
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
private String linkForInstance(ExampleScenarioInstanceContainedInstanceComponent ref) {
|
||||
String plantUml = "#i_" + ref.getInstanceReference();
|
||||
if (ref.hasVersionReference())
|
||||
plantUml += "v_" + ref.getVersionReference();
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
private String trimPrefix(String prefix){
|
||||
return prefix.substring(prefix.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private String noteOver(List<ExampleScenarioActorComponent> actors, String text) {
|
||||
String plantUml = "Note over ";
|
||||
List actorKeys = new ArrayList<String>();
|
||||
for (ExampleScenarioActorComponent actor: actors) {
|
||||
actorKeys.add(actor.getKey());
|
||||
}
|
||||
plantUml += String.join(", ", actorKeys);
|
||||
plantUml += " " + text;
|
||||
return plantUml;
|
||||
}
|
||||
|
||||
private String creolLink(String text, String url) {
|
||||
return creolLink(text, url, null);
|
||||
}
|
||||
|
||||
private String creolLink(String text, String url, String flyover) {
|
||||
String s = "[[" + url;
|
||||
if (flyover!=null)
|
||||
s += "{" + flyover + "}";
|
||||
s += " " + text + "]]";
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean renderActors(XhtmlNode x, ExampleScenario scen) throws IOException {
|
||||
XhtmlNode tbl = x.table("table-striped table-bordered");
|
||||
XhtmlNode thead = tbl.tr();
|
||||
thead.th().addText("Name");
|
||||
thead.th().addText("Type");
|
||||
thead.th().addText("Description");
|
||||
for (ExampleScenarioActorComponent actor : scen.getActor()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
XhtmlNode nameCell = tr.td();
|
||||
nameCell.an("a_" + actor.getKey());
|
||||
nameCell.tx(actor.getTitle());
|
||||
tr.td().tx(actor.getType().getDisplay());
|
||||
addMarkdown(tr.td().style("overflow-wrap:break-word"), actor.getDescription());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean renderInstances(XhtmlNode x, ExampleScenario scen) throws IOException {
|
||||
XhtmlNode tbl = x.table("table-striped table-bordered");
|
||||
XhtmlNode thead = tbl.tr();
|
||||
thead.th().addText("Name");
|
||||
thead.th().addText("Type");
|
||||
thead.th().addText("Content");
|
||||
thead.th().addText("Description");
|
||||
|
||||
Map<String, String> instanceNames = new HashMap<String, String>();
|
||||
for (ExampleScenarioInstanceComponent instance : scen.getInstance()) {
|
||||
instanceNames.put("i_" + instance.getKey(), instance.getTitle());
|
||||
if (instance.hasVersion()) {
|
||||
for (ExampleScenarioInstanceVersionComponent version: instance.getVersion()) {
|
||||
instanceNames.put("i_" + instance.getKey() + "v_" + version.getKey(), version.getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ExampleScenarioInstanceComponent instance : scen.getInstance()) {
|
||||
XhtmlNode row = tbl.tr();
|
||||
XhtmlNode nameCell = row.td();
|
||||
nameCell.an("i_" + instance.getKey());
|
||||
nameCell.tx(instance.getTitle());
|
||||
XhtmlNode typeCell = row.td();
|
||||
if (instance.hasVersion())
|
||||
typeCell.attribute("rowSpan", Integer.toString(instance.getVersion().size()+1));
|
||||
|
||||
if (!instance.hasStructureVersion() || instance.getStructureType().getSystem().equals("")) {
|
||||
if (instance.hasStructureVersion())
|
||||
typeCell.tx("FHIR version " + instance.getStructureVersion() + " ");
|
||||
if (instance.hasStructureProfile()) {
|
||||
renderCanonical(scen, typeCell, instance.getStructureProfile().toString());
|
||||
} else {
|
||||
renderCanonical(scen, typeCell, "http://hl7.org/fhir/StructureDefinition/" + instance.getStructureType().getCode());
|
||||
}
|
||||
} else {
|
||||
render(typeCell, instance.getStructureVersionElement());
|
||||
typeCell.tx(" version " + instance.getStructureVersion());
|
||||
if (instance.hasStructureProfile()) {
|
||||
typeCell.tx(" ");
|
||||
renderCanonical(scen, typeCell, instance.getStructureProfile().toString());
|
||||
}
|
||||
}
|
||||
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(scen, row.td(), instance.getContent().copy().setDisplay("here"));
|
||||
context.setMode(mode);
|
||||
} else
|
||||
row.td();
|
||||
|
||||
XhtmlNode descCell = row.td();
|
||||
addMarkdown(descCell, instance.getDescription());
|
||||
if (instance.hasContainedInstance()) {
|
||||
descCell.b().tx("Contains: ");
|
||||
int containedCount = 1;
|
||||
for (ExampleScenarioInstanceContainedInstanceComponent contained: instance.getContainedInstance()) {
|
||||
String key = "i_" + contained.getInstanceReference();
|
||||
if (contained.hasVersionReference())
|
||||
key += "v_" + contained.getVersionReference();
|
||||
String description = instanceNames.get(key);
|
||||
if (description==null)
|
||||
throw new FHIRException("Unable to find contained instance " + key + " under " + instance.getKey());
|
||||
descCell.ah("#" + key).tx(description);
|
||||
containedCount++;
|
||||
if (instance.getContainedInstance().size() > containedCount)
|
||||
descCell.tx(", ");
|
||||
}
|
||||
}
|
||||
|
||||
for (ExampleScenarioInstanceVersionComponent version: instance.getVersion()) {
|
||||
row = tbl.tr();
|
||||
nameCell = row.td().style("padding-left: 10px;");
|
||||
nameCell.an("i_" + instance.getKey() + "v_" + version.getKey());
|
||||
XhtmlNode nameItem = nameCell.ul().li();
|
||||
nameItem.tx(version.getTitle());
|
||||
|
||||
if (version.hasContent() && version.getContent().hasReference()) {
|
||||
// Force end-user mode to avoid ugly references
|
||||
RenderingContext.ResourceRendererMode mode = context.getMode();
|
||||
context.setMode(RenderingContext.ResourceRendererMode.END_USER);
|
||||
renderReference(scen, row.td(), version.getContent().copy().setDisplay("here"));
|
||||
context.setMode(mode);
|
||||
} else
|
||||
row.td();
|
||||
|
||||
descCell = row.td();
|
||||
addMarkdown(descCell, instance.getDescription());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean renderProcesses(XhtmlNode x, ExampleScenario scen) throws IOException {
|
||||
Map<String, ExampleScenarioActorComponent> actors = new HashMap<>();
|
||||
for (ExampleScenarioActorComponent actor: scen.getActor()) {
|
||||
actors.put(actor.getKey(), actor);
|
||||
}
|
||||
|
||||
Map<String, ExampleScenarioInstanceComponent> instances = new HashMap<>();
|
||||
for (ExampleScenarioInstanceComponent instance: scen.getInstance()) {
|
||||
instances.put(instance.getKey(), instance);
|
||||
}
|
||||
|
||||
int num = 1;
|
||||
for (ExampleScenarioProcessComponent process : scen.getProcess()) {
|
||||
renderProcess(x, process, Integer.toString(num), actors, instances);
|
||||
num++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void renderProcess(XhtmlNode x, ExampleScenarioProcessComponent process, String prefix, Map<String, ExampleScenarioActorComponent> actors, Map<String, ExampleScenarioInstanceComponent> instances) throws IOException {
|
||||
XhtmlNode div = x.div();
|
||||
div.an("p_" + prefix);
|
||||
div.b().tx("Process: " + process.getTitle());
|
||||
if (process.hasDescription())
|
||||
addMarkdown(div, process.getDescription());
|
||||
if (process.hasPreConditions()) {
|
||||
div.para().b().i().tx("Pre-conditions:");
|
||||
addMarkdown(div, process.getPreConditions());
|
||||
}
|
||||
if (process.hasPostConditions()) {
|
||||
div.para().b().i().tx("Post-conditions:");
|
||||
addMarkdown(div, process.getPostConditions());
|
||||
}
|
||||
XhtmlNode tbl = div.table("table-striped table-bordered").style("width:100%");
|
||||
XhtmlNode thead = tbl.tr();
|
||||
thead.th().addText("Step");
|
||||
thead.th().addText("Name");
|
||||
thead.th().addText("Description");
|
||||
thead.th().addText("Initator");
|
||||
thead.th().addText("Receiver");
|
||||
thead.th().addText("Request");
|
||||
thead.th().addText("Response");
|
||||
int stepCount = 1;
|
||||
for (ExampleScenarioProcessStepComponent step: process.getStep()) {
|
||||
renderStep(tbl, step, stepPrefix(prefix, step, stepCount), actors, instances);
|
||||
stepCount++;
|
||||
}
|
||||
|
||||
// Now go through the steps again and spit out any child processes
|
||||
stepCount = 1;
|
||||
for (ExampleScenarioProcessStepComponent step: process.getStep()) {
|
||||
stepSubProcesses(tbl, step, stepPrefix(prefix, step, stepCount), actors, instances);
|
||||
stepCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private String stepPrefix(String prefix, ExampleScenarioProcessStepComponent step, int stepCount) {
|
||||
String num = step.hasNumber() ? step.getNumber() : Integer.toString(stepCount);
|
||||
return (!prefix.isEmpty() ? prefix + "." : "") + num;
|
||||
}
|
||||
|
||||
private String altStepPrefix(String prefix, ExampleScenarioProcessStepComponent step, int altNum, int stepCount) {
|
||||
return stepPrefix(prefix + "-Alt" + Integer.toString(altNum) + ".", step, stepCount);
|
||||
}
|
||||
|
||||
private void stepSubProcesses(XhtmlNode x, ExampleScenarioProcessStepComponent step, String prefix, Map<String, ExampleScenarioActorComponent> actors, Map<String, ExampleScenarioInstanceComponent> instances) throws IOException {
|
||||
if (step.hasProcess())
|
||||
renderProcess(x, step.getProcess(), prefix, actors, instances);
|
||||
if (step.hasAlternative()) {
|
||||
int altNum = 1;
|
||||
for (ExampleScenarioProcessStepAlternativeComponent alt: step.getAlternative()) {
|
||||
int stepCount = 1;
|
||||
for (ExampleScenarioProcessStepComponent altStep: alt.getStep()) {
|
||||
stepSubProcesses(x, altStep, altStepPrefix(prefix, altStep, altNum, stepCount), actors, instances);
|
||||
stepCount++;
|
||||
}
|
||||
altNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean renderStep(XhtmlNode tbl, ExampleScenarioProcessStepComponent step, String stepLabel, Map<String, ExampleScenarioActorComponent> actors, Map<String, ExampleScenarioInstanceComponent> instances) throws IOException {
|
||||
XhtmlNode row = tbl.tr();
|
||||
XhtmlNode prefixCell = row.td();
|
||||
prefixCell.an("s_" + stepLabel);
|
||||
prefixCell.tx(stepLabel.substring(stepLabel.indexOf(".") + 1));
|
||||
if (step.hasProcess()) {
|
||||
XhtmlNode n = row.td().colspan(6);
|
||||
n.tx("See subprocess" );
|
||||
n.ah("#p_" + stepLabel, step.getProcess().getTitle());
|
||||
n.tx(" below");
|
||||
|
||||
} else if (step.hasWorkflow()) {
|
||||
XhtmlNode n = row.td().colspan(6);
|
||||
n.tx("See other scenario ");
|
||||
String link = new ContextUtilities(context.getWorker()).getLinkForUrl(context.getLink(KnownLinkType.SPEC), step.getWorkflow());
|
||||
n.ah(link, step.getProcess().getTitle());
|
||||
|
||||
} else {
|
||||
// Must be an operation
|
||||
ExampleScenarioProcessStepOperationComponent op = step.getOperation();
|
||||
XhtmlNode name = row.td();
|
||||
name.tx(op.getTitle());
|
||||
if (op.hasType()) {
|
||||
name.tx(" - ");
|
||||
renderCoding(name, op.getType());
|
||||
}
|
||||
XhtmlNode descCell = row.td();
|
||||
addMarkdown(descCell, op.getDescription());
|
||||
|
||||
addActor(row, op.getInitiator(), actors);
|
||||
addActor(row, op.getReceiver(), actors);
|
||||
addInstance(row, op.getRequest(), instances);
|
||||
addInstance(row, op.getResponse(), instances);
|
||||
}
|
||||
|
||||
int altNum = 1;
|
||||
for (ExampleScenarioProcessStepAlternativeComponent alt : step.getAlternative()) {
|
||||
XhtmlNode altHeading = tbl.tr().colspan(7).td();
|
||||
altHeading.para().i().tx("Alternative " + alt.getTitle());
|
||||
if (alt.hasDescription())
|
||||
addMarkdown(altHeading, alt.getDescription());
|
||||
int stepCount = 1;
|
||||
for (ExampleScenarioProcessStepComponent subStep : alt.getStep()) {
|
||||
renderStep(tbl, subStep, altStepPrefix(stepLabel, step, altNum, stepCount), actors, instances);
|
||||
stepCount++;
|
||||
}
|
||||
altNum++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addActor(XhtmlNode row, String actorId, Map<String, ExampleScenarioActorComponent> actors) throws FHIRException {
|
||||
XhtmlNode actorCell = row.td();
|
||||
if (actorId==null)
|
||||
return;
|
||||
ExampleScenarioActorComponent actor = actors.get(actorId);
|
||||
if (actor==null)
|
||||
throw new FHIRException("Unable to find referenced actor " + actorId);
|
||||
actorCell.ah("#a_" + actor.getKey(), actor.getDescription()).tx(actor.getTitle());
|
||||
}
|
||||
|
||||
private void addInstance(XhtmlNode row, ExampleScenarioInstanceContainedInstanceComponent instanceRef, Map<String, ExampleScenarioInstanceComponent> instances) {
|
||||
XhtmlNode instanceCell = row.td();
|
||||
if (instanceRef==null || instanceRef.getInstanceReference()==null)
|
||||
return;
|
||||
ExampleScenarioInstanceComponent instance = instances.get(instanceRef.getInstanceReference());
|
||||
if (instance==null)
|
||||
throw new FHIRException("Unable to find referenced instance " + instanceRef.getInstanceReference());
|
||||
if (instanceRef.hasVersionReference()) {
|
||||
ExampleScenarioInstanceVersionComponent theVersion = null;
|
||||
for (ExampleScenarioInstanceVersionComponent version: instance.getVersion()) {
|
||||
if (version.getKey().equals(instanceRef.getVersionReference())) {
|
||||
theVersion = version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (theVersion==null)
|
||||
throw new FHIRException("Unable to find referenced version " + instanceRef.getVersionReference() + " within instance " + instanceRef.getInstanceReference());
|
||||
instanceCell.ah("#i_" + instance.getKey() + "v_"+ theVersion.getKey() , theVersion.getDescription()).tx(theVersion.getTitle());
|
||||
|
||||
} else
|
||||
instanceCell.ah("#i_" + instance.getKey(), instance.getDescription()).tx(instance.getTitle());
|
||||
}
|
||||
}
|
|
@ -80,7 +80,30 @@ public class RenderingContext {
|
|||
BINDINGS, // tree/name + column for each kind of binding found, cells are lists of bindings
|
||||
OBLIGATIONS, // tree/name + column for each actor that has obligations
|
||||
}
|
||||
|
||||
|
||||
public enum ExampleScenarioRendererMode {
|
||||
/**
|
||||
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
|
||||
* Note that this is not the same as how the questionnaire would like on a form filler, since all dynamic behavior is ignored
|
||||
*/
|
||||
ACTORS,
|
||||
|
||||
/**
|
||||
* A table listing all the instances (and versions there-of) used in a scenario
|
||||
*/
|
||||
INSTANCES,
|
||||
|
||||
/**
|
||||
* Information about the processes (and sub-processes) defined in a scenario
|
||||
*/
|
||||
PROCESSES,
|
||||
|
||||
/**
|
||||
* A diagram showing interactions between the actors as part of the process steps
|
||||
*/
|
||||
DIAGRAM
|
||||
}
|
||||
|
||||
public enum QuestionnaireRendererMode {
|
||||
/**
|
||||
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
|
||||
|
@ -146,6 +169,7 @@ public class RenderingContext {
|
|||
private boolean inlineGraphics;
|
||||
private StandardsStatus defaultStandardsStatus;
|
||||
|
||||
private ExampleScenarioRendererMode scenarioMode = null;
|
||||
private QuestionnaireRendererMode questionnaireMode = QuestionnaireRendererMode.FORM;
|
||||
private StructureDefinitionRendererMode structureMode = StructureDefinitionRendererMode.SUMMARY;
|
||||
|
||||
|
@ -211,6 +235,7 @@ public class RenderingContext {
|
|||
res.definitionsTarget = definitionsTarget;
|
||||
res.destDir = destDir;
|
||||
res.addGeneratedNarrativeHeader = addGeneratedNarrativeHeader;
|
||||
res.scenarioMode = scenarioMode;
|
||||
res.questionnaireMode = questionnaireMode;
|
||||
res.structureMode = structureMode;
|
||||
res.header = header;
|
||||
|
@ -440,6 +465,15 @@ public class RenderingContext {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ExampleScenarioRendererMode getScenarioMode() {
|
||||
return scenarioMode;
|
||||
}
|
||||
|
||||
public RenderingContext setScenarioMode(ExampleScenarioRendererMode scenarioMode) {
|
||||
this.scenarioMode = scenarioMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestionnaireRendererMode getQuestionnaireMode() {
|
||||
return questionnaireMode;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue