Merge pull request #1055 from hapifhir/gg-202301-profile-rendering
Gg 202301 profile rendering
This commit is contained in:
commit
ff0fd98539
|
@ -13,8 +13,8 @@ import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.UnusedTracker;
|
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.formats.IParser;
|
import org.hl7.fhir.r5.formats.IParser;
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
@ -33,10 +32,16 @@ import org.hl7.fhir.r5.model.StringType;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer;
|
||||||
|
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.utils.DefinitionNavigator;
|
import org.hl7.fhir.r5.utils.DefinitionNavigator;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
|
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
|
||||||
|
@ -988,22 +993,27 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
String sn = getSliceName(combined);
|
String sn = getSliceName(combined);
|
||||||
if (sn != null)
|
if (sn != null)
|
||||||
sName = sName +":"+sn;
|
sName = sName +":"+sn;
|
||||||
UnusedTracker used = new UnusedTracker();
|
StructureDefinitionRenderer.UnusedTracker used = new StructureDefinitionRenderer.UnusedTracker();
|
||||||
|
StructureDefinitionRenderer sdrLeft = new StructureDefinitionRenderer(new RenderingContext(utilsLeft.getContext(), null, utilsLeft.getTerminologyServiceOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
|
||||||
|
StructureDefinitionRenderer sdrRight= new StructureDefinitionRenderer(new RenderingContext(utilsRight.getContext(), null, utilsRight.getTerminologyServiceOptions(), corePath, prefix, null, ResourceRendererMode.TECHNICAL, GenerationRules.IG_PUBLISHER));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Cell nc;
|
Cell nc;
|
||||||
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||||
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||||
if (combined.hasLeft()) {
|
if (combined.hasLeft()) {
|
||||||
nc = utilsLeft.genElementNameCell(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, false, ext, used , ref, sName, null);
|
nc = sdrLeft.genElementNameCell(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, false, ext, used , ref, sName, null);
|
||||||
} else {
|
} else {
|
||||||
nc = utilsRight.genElementNameCell(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, false, ext, used , ref, sName, null);
|
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()) {
|
if (combined.hasLeft()) {
|
||||||
frame(utilsLeft.genElementCells(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, true, ext, used , ref, sName, nc, false, false, null), leftColor);
|
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, null), leftColor);
|
||||||
} else {
|
} else {
|
||||||
frame(spacers(row, 4, gen), leftColor);
|
frame(spacers(row, 4, gen), leftColor);
|
||||||
}
|
}
|
||||||
if (combined.hasRight()) {
|
if (combined.hasRight()) {
|
||||||
frame(utilsRight.genElementCells(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, true, ext, used, ref, sName, nc, false, false, null), rightColor);
|
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, null), rightColor);
|
||||||
} else {
|
} else {
|
||||||
frame(spacers(row, 4, gen), rightColor);
|
frame(spacers(row, 4, gen), rightColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,29 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.BindingResolution;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution;
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.Extension;
|
import org.hl7.fhir.r5.model.Extension;
|
||||||
|
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r5.model.UsageContext;
|
import org.hl7.fhir.r5.model.UsageContext;
|
||||||
|
import org.hl7.fhir.r5.renderers.CodeResolver;
|
||||||
|
import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
|
||||||
import org.hl7.fhir.r5.renderers.DataRenderer;
|
import org.hl7.fhir.r5.renderers.DataRenderer;
|
||||||
import org.hl7.fhir.r5.renderers.IMarkdownProcessor;
|
import org.hl7.fhir.r5.renderers.IMarkdownProcessor;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
|
import org.hl7.fhir.r5.utils.PublicationHacker;
|
||||||
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
|
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
|
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
|
||||||
|
@ -23,6 +34,7 @@ import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
|
||||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
import org.hl7.fhir.utilities.xhtml.XhtmlNodeList;
|
||||||
|
|
||||||
public class AdditionalBindingsRenderer {
|
public class AdditionalBindingsRenderer {
|
||||||
public class AdditionalBindingDetail {
|
public class AdditionalBindingDetail {
|
||||||
|
@ -78,14 +90,16 @@ public class AdditionalBindingsRenderer {
|
||||||
private String path;
|
private String path;
|
||||||
private RenderingContext context;
|
private RenderingContext context;
|
||||||
private IMarkdownProcessor md;
|
private IMarkdownProcessor md;
|
||||||
|
private CodeResolver cr;
|
||||||
|
|
||||||
public AdditionalBindingsRenderer(ProfileKnowledgeProvider pkp, String corePath, StructureDefinition profile, String path, RenderingContext context, IMarkdownProcessor md) {
|
public AdditionalBindingsRenderer(ProfileKnowledgeProvider pkp, String corePath, StructureDefinition profile, String path, RenderingContext context, IMarkdownProcessor md, CodeResolver cr) {
|
||||||
this.pkp = pkp;
|
this.pkp = pkp;
|
||||||
this.corePath = corePath;
|
this.corePath = corePath;
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.md = md;
|
this.md = md;
|
||||||
|
this.cr = cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seeMaxBinding(Extension ext) {
|
public void seeMaxBinding(Extension ext) {
|
||||||
|
@ -106,7 +120,7 @@ public class AdditionalBindingsRenderer {
|
||||||
abr.compare = new AdditionalBindingDetail();
|
abr.compare = new AdditionalBindingDetail();
|
||||||
abr.compare.valueSet = compExt==null ? null : compExt.getValue().primitiveValue();
|
abr.compare.valueSet = compExt==null ? null : compExt.getValue().primitiveValue();
|
||||||
} else {
|
} else {
|
||||||
abr.isUnchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
|
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
||||||
}
|
}
|
||||||
bindings.add(abr);
|
bindings.add(abr);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +180,7 @@ public class AdditionalBindingsRenderer {
|
||||||
abr.docoShort = ext.getExtensionString("shortDoco");
|
abr.docoShort = ext.getExtensionString("shortDoco");
|
||||||
abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext() ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
|
abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext() ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
|
||||||
abr.any = "any".equals(ext.getExtensionString("scope"));
|
abr.any = "any".equals(ext.getExtensionString("scope"));
|
||||||
abr.isUnchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
|
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
||||||
return abr;
|
return abr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,16 +323,19 @@ public class AdditionalBindingsRenderer {
|
||||||
case "minimum":
|
case "minimum":
|
||||||
td.ah(corePath+"extension-elementdefinition-minvalueset.html", "The minimum allowable value set - any conformant system SHALL support all these codes").tx("Min Binding");
|
td.ah(corePath+"extension-elementdefinition-minvalueset.html", "The minimum allowable value set - any conformant system SHALL support all these codes").tx("Min Binding");
|
||||||
break;
|
break;
|
||||||
case "conformance" :
|
case "required" :
|
||||||
td.ah(corePath+"terminologies.html#strength", "Validators will check this binding (strength = required)").tx("Validation Binding");
|
td.ah(corePath+"terminologies.html#strength", "Validators will check this binding (strength = required)").tx("Validation Binding");
|
||||||
break;
|
break;
|
||||||
|
case "extensible" :
|
||||||
|
td.ah(corePath+"terminologies.html#strength", "Validators will check this binding (strength = extensible)").tx("Validation Binding");
|
||||||
|
break;
|
||||||
case "candidate" :
|
case "candidate" :
|
||||||
td.ah(corePath+"terminologies.html#strength", "This is a candidate binding that constraints on this profile may consider (see doco)").tx("Candidate Validation Binding");
|
td.ah(corePath+"terminologies.html#strength", "This is a candidate binding that constraints on this profile may consider (see doco)").tx("Candidate Validation Binding");
|
||||||
break;
|
break;
|
||||||
case "current" :
|
case "current" :
|
||||||
td.span(null, "New records are required to use this value set, but legacy records may use other codes").tx("Required");
|
td.span(null, "New records are required to use this value set, but legacy records may use other codes").tx("Required");
|
||||||
break;
|
break;
|
||||||
case "recommended" :
|
case "preferred" :
|
||||||
td.span(null, "This is the value set that is recommended (documentation should explain why)").tx("Recommended");
|
td.span(null, "This is the value set that is recommended (documentation should explain why)").tx("Recommended");
|
||||||
break;
|
break;
|
||||||
case "ui" :
|
case "ui" :
|
||||||
|
@ -346,5 +363,60 @@ public class AdditionalBindingsRenderer {
|
||||||
return !bindings.isEmpty();
|
return !bindings.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void render(XhtmlNodeList children, List<ElementDefinitionBindingAdditionalComponent> list) {
|
||||||
|
if (list.size() == 1) {
|
||||||
|
render(children, list.get(0));
|
||||||
|
} else {
|
||||||
|
XhtmlNode ul = children.ul();
|
||||||
|
for (ElementDefinitionBindingAdditionalComponent b : list) {
|
||||||
|
render(ul.li().getChildNodes(), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void render(XhtmlNodeList children, ElementDefinitionBindingAdditionalComponent b) {
|
||||||
|
if (b.getValueSet() == null) {
|
||||||
|
return; // what should happen?
|
||||||
|
}
|
||||||
|
BindingResolution br = pkp.resolveBinding(profile, b.getValueSet(), corePath);
|
||||||
|
XhtmlNode a = children.ah(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !context.getPkp().prependLinks() ? br.url : corePath+br.url, b.hasDocumentation() ? b.getDocumentation() : null);
|
||||||
|
if (b.hasDocumentation()) {
|
||||||
|
a.attribute("title", b.getDocumentation());
|
||||||
|
}
|
||||||
|
a.tx(br.display);
|
||||||
|
|
||||||
|
if (b.hasShortDoco()) {
|
||||||
|
children.tx(": ");
|
||||||
|
children.tx(b.getShortDoco());
|
||||||
|
}
|
||||||
|
if (b.getAny() || b.hasUsage()) {
|
||||||
|
children.tx(" (");
|
||||||
|
boolean ffirst = !b.getAny();
|
||||||
|
if (b.getAny()) {
|
||||||
|
children.tx("any repeat");
|
||||||
|
}
|
||||||
|
for (UsageContext uc : b.getUsage()) {
|
||||||
|
if (ffirst) ffirst = false; else children.tx(",");
|
||||||
|
if (!uc.getCode().is("http://terminology.hl7.org/CodeSystem/usage-context-type", "jurisdiction")) {
|
||||||
|
children.tx(displayForUsage(uc.getCode()));
|
||||||
|
children.tx("=");
|
||||||
|
}
|
||||||
|
CodeResolution ccr = cr.resolveCode(uc.getValueCodeableConcept());
|
||||||
|
children.ah(ccr.getLink(), ccr.getHint()).tx(ccr.getDisplay());
|
||||||
|
}
|
||||||
|
children.tx(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String displayForUsage(Coding c) {
|
||||||
|
if (c.hasDisplay()) {
|
||||||
|
return c.getDisplay();
|
||||||
|
}
|
||||||
|
if ("http://terminology.hl7.org/CodeSystem/usage-context-type".equals(c.getSystem())) {
|
||||||
|
return c.getCode();
|
||||||
|
}
|
||||||
|
return c.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.hl7.fhir.r5.conformance.profile;
|
||||||
|
|
||||||
|
public class BindingResolution {
|
||||||
|
public BindingResolution(String display, String url) {
|
||||||
|
this.display = display;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
public BindingResolution() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
public String display;
|
||||||
|
public String url;
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
package org.hl7.fhir.r5.conformance.profile;
|
package org.hl7.fhir.r5.conformance.profile;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
|
||||||
|
|
||||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class PathSlicingParams {
|
public class PathSlicingParams {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.hl7.fhir.r5.conformance.profile;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
|
||||||
|
public interface ProfileKnowledgeProvider {
|
||||||
|
boolean isDatatype(String typeSimple);
|
||||||
|
boolean isPrimitiveType(String typeSimple);
|
||||||
|
boolean isResource(String typeSimple);
|
||||||
|
boolean hasLinkFor(String typeSimple);
|
||||||
|
String getLinkFor(String corePath, String typeSimple);
|
||||||
|
BindingResolution resolveBinding(StructureDefinition def,
|
||||||
|
ElementDefinitionBindingComponent binding, String path) throws FHIRException;
|
||||||
|
BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException;
|
||||||
|
String getLinkForProfile(StructureDefinition profile, String url);
|
||||||
|
boolean prependLinks();
|
||||||
|
String getLinkForUrl(String corePath, String s);
|
||||||
|
}
|
|
@ -1,24 +1,26 @@
|
||||||
package org.hl7.fhir.r5.conformance.profile;
|
package org.hl7.fhir.r5.conformance.profile;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import java.util.ArrayList;
|
||||||
import lombok.AllArgsConstructor;
|
import java.util.Iterator;
|
||||||
import lombok.Getter;
|
import java.util.List;
|
||||||
import lombok.With;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.conformance.ElementRedirection;
|
import org.hl7.fhir.r5.conformance.ElementRedirection;
|
||||||
import org.hl7.fhir.r5.model.CanonicalType;
|
import org.hl7.fhir.r5.model.CanonicalType;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionSnapshotComponent;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import lombok.AccessLevel;
|
||||||
import java.util.Iterator;
|
import lombok.AllArgsConstructor;
|
||||||
import java.util.List;
|
import lombok.Getter;
|
||||||
import java.util.Set;
|
import lombok.With;
|
||||||
|
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class ProfilePathProcessor {
|
public class ProfilePathProcessor {
|
||||||
|
@ -279,7 +281,7 @@ public class ProfilePathProcessor {
|
||||||
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.NOT_DONE_YET));
|
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.NOT_DONE_YET));
|
||||||
}
|
}
|
||||||
if (profileUtilities.hasInnerDiffMatches(getDifferential(), currentBasePath, cursors.diffCursor, getDiffLimit(), cursors.base.getElement(), false)) {
|
if (profileUtilities.hasInnerDiffMatches(getDifferential(), currentBasePath, cursors.diffCursor, getDiffLimit(), cursors.base.getElement(), false)) {
|
||||||
if (profileUtilities.baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
if (baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
||||||
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ " + currentBasePath + " | " + currentBase.getPath() + ")");
|
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ " + currentBasePath + " | " + currentBase.getPath() + ")");
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = profileUtilities.getTypeForElement(getDifferential(), cursors.diffCursor, getProfileName(), diffMatches, outcome, getWebUrl(), getDerived());
|
StructureDefinition dt = profileUtilities.getTypeForElement(getDifferential(), cursors.diffCursor, getProfileName(), diffMatches, outcome, getWebUrl(), getDerived());
|
||||||
|
@ -689,6 +691,28 @@ public class ProfilePathProcessor {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int indexOfFirstNonChild(StructureDefinitionSnapshotComponent base, ElementDefinition currentBase, int i, int baseLimit) {
|
||||||
|
return baseLimit+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean baseHasChildren(StructureDefinitionSnapshotComponent base, ElementDefinition ed) {
|
||||||
|
int index = base.getElement().indexOf(ed);
|
||||||
|
if (index == -1 || index >= base.getElement().size()-1)
|
||||||
|
return false;
|
||||||
|
String p = base.getElement().get(index+1).getPath();
|
||||||
|
return isChildOf(p, ed.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isChildOf(String sub, String focus) {
|
||||||
|
if (focus.endsWith("[x]")) {
|
||||||
|
focus = focus.substring(0, focus.length()-3);
|
||||||
|
return sub.startsWith(focus);
|
||||||
|
} else
|
||||||
|
return sub.startsWith(focus+".");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void processSimplePathWithEmptyDiffMatches(ElementDefinition currentBase, String currentBasePath, List<ElementDefinition> diffMatches, ProfilePathProcessorState cursors) {
|
private void processSimplePathWithEmptyDiffMatches(ElementDefinition currentBase, String currentBasePath, List<ElementDefinition> diffMatches, ProfilePathProcessorState cursors) {
|
||||||
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
|
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
|
||||||
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
|
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
|
||||||
|
@ -703,10 +727,10 @@ public class ProfilePathProcessor {
|
||||||
if (profileUtilities.hasInnerDiffMatches(getDifferential(), currentBasePath, cursors.diffCursor, getDiffLimit(), cursors.base.getElement(), true)) {
|
if (profileUtilities.hasInnerDiffMatches(getDifferential(), currentBasePath, cursors.diffCursor, getDiffLimit(), cursors.base.getElement(), true)) {
|
||||||
// well, the profile walks into this, so we need to as well
|
// well, the profile walks into this, so we need to as well
|
||||||
// did we implicitly step into a new type?
|
// did we implicitly step into a new type?
|
||||||
if (profileUtilities.baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
if (baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
||||||
|
|
||||||
this.incrementDebugIndent().withSlicing(new PathSlicingParams()). processPaths( new ProfilePathProcessorState(cursors.base, cursors.baseCursor + 1, cursors.diffCursor, cursors.contextName, cursors.resultPathBase));
|
this.incrementDebugIndent().withSlicing(new PathSlicingParams()). processPaths( new ProfilePathProcessorState(cursors.base, cursors.baseCursor + 1, cursors.diffCursor, cursors.contextName, cursors.resultPathBase));
|
||||||
cursors.baseCursor = profileUtilities.indexOfFirstNonChild(cursors.base, currentBase, cursors.baseCursor + 1, getBaseLimit());
|
cursors.baseCursor = indexOfFirstNonChild(cursors.base, currentBase, cursors.baseCursor + 1, getBaseLimit());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (outcome.getType().size() == 0 && !outcome.hasContentReference()) {
|
if (outcome.getType().size() == 0 && !outcome.hasContentReference()) {
|
||||||
|
@ -858,7 +882,7 @@ public class ProfilePathProcessor {
|
||||||
profileUtilities.updateFromDefinition(outcome, diffMatches.get(0), getProfileName(), closed, getUrl(), getSourceStructureDefinition(), getDerived()); // if there's no slice, we don't want to update the unsliced description
|
profileUtilities.updateFromDefinition(outcome, diffMatches.get(0), getProfileName(), closed, getUrl(), getSourceStructureDefinition(), getDerived()); // if there's no slice, we don't want to update the unsliced description
|
||||||
profileUtilities.removeStatusExtensions(outcome);
|
profileUtilities.removeStatusExtensions(outcome);
|
||||||
} else if (!diffMatches.get(0).hasSliceName()) {
|
} else if (!diffMatches.get(0).hasSliceName()) {
|
||||||
diffMatches.get(0).setUserData(profileUtilities.GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called
|
diffMatches.get(0).setUserData(profileUtilities.UD_GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called
|
||||||
}
|
}
|
||||||
|
|
||||||
getResult().getElement().add(outcome);
|
getResult().getElement().add(outcome);
|
||||||
|
@ -954,8 +978,8 @@ public class ProfilePathProcessor {
|
||||||
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
|
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
|
||||||
if (!outcome.getPath().startsWith(cursors.resultPathBase))
|
if (!outcome.getPath().startsWith(cursors.resultPathBase))
|
||||||
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH));
|
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH));
|
||||||
outcome.setUserData(profileUtilities.BASE_PATH, outcome.getPath());
|
outcome.setUserData(profileUtilities.UD_BASE_PATH, outcome.getPath());
|
||||||
outcome.setUserData(profileUtilities.BASE_MODEL, getSourceStructureDefinition().getUrl());
|
outcome.setUserData(profileUtilities.UD_BASE_MODEL, getSourceStructureDefinition().getUrl());
|
||||||
getResult().getElement().add(outcome);
|
getResult().getElement().add(outcome);
|
||||||
cursors.baseCursor++;
|
cursors.baseCursor++;
|
||||||
}
|
}
|
||||||
|
@ -1223,13 +1247,13 @@ public class ProfilePathProcessor {
|
||||||
getResult().getElement().add(outcome);
|
getResult().getElement().add(outcome);
|
||||||
// the profile walks into this, so we need to as well
|
// the profile walks into this, so we need to as well
|
||||||
// did we implicitly step into a new type?
|
// did we implicitly step into a new type?
|
||||||
if (profileUtilities.baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
if (baseHasChildren(cursors.base, currentBase)) { // not a new type here
|
||||||
|
|
||||||
this
|
this
|
||||||
.incrementDebugIndent()
|
.incrementDebugIndent()
|
||||||
.withSlicing(new PathSlicingParams()).processPaths(
|
.withSlicing(new PathSlicingParams()).processPaths(
|
||||||
new ProfilePathProcessorState(cursors.base, cursors.baseCursor + 1, cursors.diffCursor, cursors.contextName, cursors.resultPathBase));
|
new ProfilePathProcessorState(cursors.base, cursors.baseCursor + 1, cursors.diffCursor, cursors.contextName, cursors.resultPathBase));
|
||||||
cursors.baseCursor = profileUtilities.indexOfFirstNonChild(cursors.base, currentBase, cursors.baseCursor, getBaseLimit());
|
cursors.baseCursor = indexOfFirstNonChild(cursors.base, currentBase, cursors.baseCursor, getBaseLimit());
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = profileUtilities.getTypeForElement(getDifferential(), cursors.diffCursor, getProfileName(), diffMatches, outcome, getWebUrl(), getDerived());
|
StructureDefinition dt = profileUtilities.getTypeForElement(getDifferential(), cursors.diffCursor, getProfileName(), diffMatches, outcome, getWebUrl(), getDerived());
|
||||||
cursors.contextName = dt.getUrl();
|
cursors.contextName = dt.getUrl();
|
||||||
|
@ -1264,8 +1288,8 @@ public class ProfilePathProcessor {
|
||||||
if (!outcome.getPath().startsWith(cursors.resultPathBase))
|
if (!outcome.getPath().startsWith(cursors.resultPathBase))
|
||||||
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, getProfileName(), outcome.getPath(), cursors.resultPathBase));
|
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, getProfileName(), outcome.getPath(), cursors.resultPathBase));
|
||||||
getResult().getElement().add(outcome); // so we just copy it in
|
getResult().getElement().add(outcome); // so we just copy it in
|
||||||
outcome.setUserData(profileUtilities.BASE_MODEL, getSourceStructureDefinition().getUrl());
|
outcome.setUserData(profileUtilities.UD_BASE_MODEL, getSourceStructureDefinition().getUrl());
|
||||||
outcome.setUserData(profileUtilities.BASE_PATH, cursors.resultPathBase);
|
outcome.setUserData(profileUtilities.UD_BASE_PATH, cursors.resultPathBase);
|
||||||
cursors.baseCursor++;
|
cursors.baseCursor++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package org.hl7.fhir.r5.conformance.profile;
|
package org.hl7.fhir.r5.conformance.profile;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
|
||||||
|
|
||||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class ProfilePathProcessorState {
|
public class ProfilePathProcessorState {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,8 +10,9 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.BindingResolution;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
import org.hl7.fhir.r5.model.CodeSystem;
|
import org.hl7.fhir.r5.model.CodeSystem;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
|
|
|
@ -613,5 +613,6 @@ public class Coding extends DataType implements IBaseCoding, ICompositeType, ICo
|
||||||
}
|
}
|
||||||
// end addition
|
// end addition
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ public class PEBuilder {
|
||||||
if (!profile.hasSnapshot()) {
|
if (!profile.hasSnapshot()) {
|
||||||
throw new DefinitionException("Profile '"+profile.getVersionedUrl()+"' does not have a snapshot");
|
throw new DefinitionException("Profile '"+profile.getVersionedUrl()+"' does not have a snapshot");
|
||||||
}
|
}
|
||||||
return new PEDefinitionResource(this, profile);
|
return new PEDefinitionResource(this, profile, profile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,7 +145,7 @@ public class PEBuilder {
|
||||||
if (!profile.hasSnapshot()) {
|
if (!profile.hasSnapshot()) {
|
||||||
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
||||||
}
|
}
|
||||||
return new PEDefinitionResource(this, profile);
|
return new PEDefinitionResource(this, profile, profile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +170,7 @@ public class PEBuilder {
|
||||||
if (!profile.hasSnapshot()) {
|
if (!profile.hasSnapshot()) {
|
||||||
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
||||||
}
|
}
|
||||||
return new PEDefinitionResource(this, profile);
|
return new PEDefinitionResource(this, profile, profile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -321,7 +321,7 @@ public class PEBuilder {
|
||||||
ElementDefinition defn = list.get(i);
|
ElementDefinition defn = list.get(i);
|
||||||
if (!defn.getMax().equals("0") && (allFixed || include(defn))) {
|
if (!defn.getMax().equals("0") && (allFixed || include(defn))) {
|
||||||
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
|
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
|
||||||
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn);
|
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn, parent.path());
|
||||||
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
|
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
|
||||||
if (cu.isPrimitiveDatatype(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
|
if (cu.isPrimitiveDatatype(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
|
||||||
pe.setMustHaveValue(definition.getMustHaveValue());
|
pe.setMustHaveValue(definition.getMustHaveValue());
|
||||||
|
@ -335,11 +335,11 @@ public class PEBuilder {
|
||||||
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
|
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
|
||||||
StructureDefinition ext = getExtensionDefinition(list.get(i));
|
StructureDefinition ext = getExtensionDefinition(list.get(i));
|
||||||
if (ext != null) {
|
if (ext != null) {
|
||||||
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), profile, list.get(i), defn, ext));
|
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), profile, list.get(i), defn, ext, parent.path()));
|
||||||
} else if (isTypeSlicing(defn)) {
|
} else if (isTypeSlicing(defn)) {
|
||||||
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn));
|
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
|
||||||
} else {
|
} else {
|
||||||
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn));
|
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path()));
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,6 @@ public class PEBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean passElementPropsCheck(ElementDefinition bdefn) {
|
private boolean passElementPropsCheck(ElementDefinition bdefn) {
|
||||||
switch (elementProps) {
|
switch (elementProps) {
|
||||||
case EXTENSION:
|
case EXTENSION:
|
||||||
|
@ -390,14 +389,14 @@ public class PEBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<PEDefinition> listSlices(StructureDefinition profileStructure, ElementDefinition definition) {
|
protected List<PEDefinition> listSlices(StructureDefinition profileStructure, ElementDefinition definition, PEDefinition parent) {
|
||||||
List<ElementDefinition> list = pu.getSliceList(profileStructure, definition);
|
List<ElementDefinition> list = pu.getSliceList(profileStructure, definition);
|
||||||
List<PEDefinition> res = new ArrayList<>();
|
List<PEDefinition> res = new ArrayList<>();
|
||||||
for (ElementDefinition ed : list) {
|
for (ElementDefinition ed : list) {
|
||||||
if (profileStructure.getDerivation() == TypeDerivationRule.CONSTRAINT && profileStructure.getType().equals("Extension")) {
|
if (profileStructure.getDerivation() == TypeDerivationRule.CONSTRAINT && profileStructure.getType().equals("Extension")) {
|
||||||
res.add(new PEDefinitionSubExtension(this, profileStructure, ed));
|
res.add(new PEDefinitionSubExtension(this, profileStructure, ed, parent.path()));
|
||||||
} else {
|
} else {
|
||||||
PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, ed);
|
PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, ed, parent.path());
|
||||||
pe.setRecursing(definition == ed || (profileStructure.getDerivation() == TypeDerivationRule.SPECIALIZATION && profileStructure.getType().equals("Extension")));
|
pe.setRecursing(definition == ed || (profileStructure.getDerivation() == TypeDerivationRule.SPECIALIZATION && profileStructure.getType().equals("Extension")));
|
||||||
res.add(pe);
|
res.add(pe);
|
||||||
}
|
}
|
||||||
|
@ -562,4 +561,8 @@ public class PEBuilder {
|
||||||
public List<Base> exec(Resource resource, Base data, String fhirpath) {
|
public List<Base> exec(Resource resource, Base data, String fhirpath) {
|
||||||
return fpe.evaluate(this, resource, resource, data, fhirpath);
|
return fpe.evaluate(this, resource, resource, data, fhirpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isResource(String name) {
|
||||||
|
return cu.isResource(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,23 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.apache.xmlbeans.impl.xb.xsdschema.All;
|
import org.apache.xmlbeans.impl.xb.xsdschema.All;
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEDefinition.PEDefinitionElementMode;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
public abstract class PEDefinition {
|
public abstract class PEDefinition {
|
||||||
|
|
||||||
|
public enum PEDefinitionElementMode {
|
||||||
|
Resource, Element, DataType, Extension
|
||||||
|
}
|
||||||
|
|
||||||
protected PEBuilder builder;
|
protected PEBuilder builder;
|
||||||
protected String name;
|
protected String name;
|
||||||
|
protected String path;
|
||||||
protected StructureDefinition profile;
|
protected StructureDefinition profile;
|
||||||
protected ElementDefinition definition;
|
protected ElementDefinition definition;
|
||||||
protected List<PEType> types;
|
protected List<PEType> types;
|
||||||
|
@ -40,11 +49,12 @@ public abstract class PEDefinition {
|
||||||
//// this.data = data;
|
//// this.data = data;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
protected PEDefinition(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition) {
|
protected PEDefinition(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, String ppath) {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.definition = definition;
|
this.definition = definition;
|
||||||
|
this.path = path == null ? name : ppath+"."+name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +65,13 @@ public abstract class PEDefinition {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path of the element or slice in the profile (name.name.name...)
|
||||||
|
*/
|
||||||
|
public String path() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The name of the element in the resource (may be different to the slice name)
|
* @return The name of the element in the resource (may be different to the slice name)
|
||||||
*/
|
*/
|
||||||
|
@ -239,6 +256,28 @@ public abstract class PEDefinition {
|
||||||
return max() > 1;
|
return max() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PEDefinitionElementMode mode() {
|
||||||
|
if (builder.isResource(definition.getBase().getPath())) {
|
||||||
|
return PEDefinitionElementMode.Resource;
|
||||||
|
}
|
||||||
|
for (TypeRefComponent tr : definition.getType()) {
|
||||||
|
if ("Extension".equals(tr.getWorkingCode())) {
|
||||||
|
return PEDefinitionElementMode.Extension;
|
||||||
|
}
|
||||||
|
if (!Utilities.existsInList(tr.getWorkingCode(), "Element", "BackboneElement")) {
|
||||||
|
return PEDefinitionElementMode.DataType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PEDefinitionElementMode.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this element is profiled one way or another
|
||||||
|
*/
|
||||||
|
public boolean isProfiled() {
|
||||||
|
return !profile.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
|
||||||
public class PEDefinitionElement extends PEDefinition {
|
public class PEDefinitionElement extends PEDefinition {
|
||||||
|
|
||||||
public PEDefinitionElement(PEBuilder builder, StructureDefinition profile, ElementDefinition definition) {
|
public PEDefinitionElement(PEBuilder builder, StructureDefinition profile, ElementDefinition definition, String ppath) {
|
||||||
super(builder, definition.getName(), profile, definition);
|
super(builder, definition.getName(), profile, definition, ppath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,7 +38,7 @@ public class PEDefinitionElement extends PEDefinition {
|
||||||
if (definition.hasSlicing()) {
|
if (definition.hasSlicing()) {
|
||||||
// get all the slices
|
// get all the slices
|
||||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
|
||||||
List<PEDefinition> slices = builder.listSlices(profile, definition);
|
List<PEDefinition> slices = builder.listSlices(profile, definition, this);
|
||||||
// list all the fhirpaths
|
// list all the fhirpaths
|
||||||
for (PEDefinition slice : slices) {
|
for (PEDefinition slice : slices) {
|
||||||
b.append("("+builder.makeSliceExpression(profile, definition.getSlicing(), slice.definition())+")");
|
b.append("("+builder.makeSliceExpression(profile, definition.getSlicing(), slice.definition())+")");
|
||||||
|
@ -52,4 +52,5 @@ public class PEDefinitionElement extends PEDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import org.hl7.fhir.r5.model.CanonicalType;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules;
|
import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEDefinition.PEDefinitionElementMode;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
|
||||||
public class PEDefinitionExtension extends PEDefinition {
|
public class PEDefinitionExtension extends PEDefinition {
|
||||||
|
@ -15,8 +17,8 @@ public class PEDefinitionExtension extends PEDefinition {
|
||||||
private ElementDefinition eed;
|
private ElementDefinition eed;
|
||||||
private ElementDefinition ved;
|
private ElementDefinition ved;
|
||||||
|
|
||||||
public PEDefinitionExtension(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition, StructureDefinition extension) {
|
public PEDefinitionExtension(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition, StructureDefinition extension, String ppath) {
|
||||||
super(builder, name, profile, definition);
|
super(builder, name, profile, definition, ppath);
|
||||||
this.sliceDefinition = sliceDefinition;
|
this.sliceDefinition = sliceDefinition;
|
||||||
this.extension= extension;
|
this.extension= extension;
|
||||||
eed = extension.getSnapshot().getElementByPath("Extension.extension");
|
eed = extension.getSnapshot().getElementByPath("Extension.extension");
|
||||||
|
@ -48,7 +50,7 @@ public class PEDefinitionExtension extends PEDefinition {
|
||||||
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
||||||
children.addAll(builder.listChildren(allFixed, this, extension, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
children.addAll(builder.listChildren(allFixed, this, extension, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||||
}
|
}
|
||||||
children.addAll(builder.listSlices(extension, eed));
|
children.addAll(builder.listSlices(extension, eed, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,4 +63,7 @@ public class PEDefinitionExtension extends PEDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PEDefinitionElementMode mode() {
|
||||||
|
return PEDefinitionElementMode.Extension;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
|
||||||
public class PEDefinitionResource extends PEDefinition {
|
public class PEDefinitionResource extends PEDefinition {
|
||||||
|
|
||||||
public PEDefinitionResource(PEBuilder builder, StructureDefinition profile) {
|
public PEDefinitionResource(PEBuilder builder, StructureDefinition profile, String ppath) {
|
||||||
super(builder, profile.getName(), profile, profile.getSnapshot().getElementFirstRep());
|
super(builder, profile.getName(), profile, profile.getSnapshot().getElementFirstRep(), ppath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,8 +11,8 @@ public class PEDefinitionSlice extends PEDefinition {
|
||||||
|
|
||||||
protected ElementDefinition sliceDefinition;
|
protected ElementDefinition sliceDefinition;
|
||||||
|
|
||||||
public PEDefinitionSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition profileDefinition, ElementDefinition sliceDefinition) {
|
public PEDefinitionSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition profileDefinition, ElementDefinition sliceDefinition, String ppath) {
|
||||||
super(builder, name, profile, profileDefinition);
|
super(builder, name, profile, profileDefinition, ppath);
|
||||||
this.sliceDefinition = sliceDefinition;
|
this.sliceDefinition = sliceDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.hl7.fhir.r5.model.CanonicalType;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules;
|
import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEDefinition.PEDefinitionElementMode;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
|
||||||
public class PEDefinitionSubExtension extends PEDefinition {
|
public class PEDefinitionSubExtension extends PEDefinition {
|
||||||
|
@ -14,8 +15,8 @@ public class PEDefinitionSubExtension extends PEDefinition {
|
||||||
private ElementDefinition ved;
|
private ElementDefinition ved;
|
||||||
private ElementDefinition ued;
|
private ElementDefinition ued;
|
||||||
|
|
||||||
public PEDefinitionSubExtension(PEBuilder builder, StructureDefinition profile, ElementDefinition definition) {
|
public PEDefinitionSubExtension(PEBuilder builder, StructureDefinition profile, ElementDefinition definition, String ppath) {
|
||||||
super(builder, definition.getSliceName(), profile, definition);
|
super(builder, definition.getSliceName(), profile, definition, ppath);
|
||||||
List<ElementDefinition> childDefs = builder.getChildren(profile, definition);
|
List<ElementDefinition> childDefs = builder.getChildren(profile, definition);
|
||||||
eed = getElementByName(childDefs, "extension");
|
eed = getElementByName(childDefs, "extension");
|
||||||
ved = getElementByName(childDefs, "value[x]");
|
ved = getElementByName(childDefs, "value[x]");
|
||||||
|
@ -56,7 +57,7 @@ public class PEDefinitionSubExtension extends PEDefinition {
|
||||||
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
||||||
children.addAll(builder.listChildren(allFixed, this, profile, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
children.addAll(builder.listChildren(allFixed, this, profile, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||||
}
|
}
|
||||||
children.addAll(builder.listSlices(profile, eed));
|
children.addAll(builder.listSlices(profile, eed, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +66,12 @@ public class PEDefinitionSubExtension extends PEDefinition {
|
||||||
if (ved.isRequired() || eed.isProhibited()) {
|
if (ved.isRequired() || eed.isProhibited()) {
|
||||||
return "extension('"+ued.getFixed().primitiveValue()+"').value";
|
return "extension('"+ued.getFixed().primitiveValue()+"').value";
|
||||||
} else {
|
} else {
|
||||||
return "extension('"+ued.getFixed().primitiveValue()+"').extension";
|
return "extension('"+ued.getFixed().primitiveValue()+"')";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PEDefinitionElementMode mode() {
|
||||||
|
return PEDefinitionElementMode.Extension;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ public class PEDefinitionTypeSlice extends PEDefinition {
|
||||||
|
|
||||||
protected ElementDefinition sliceDefinition;
|
protected ElementDefinition sliceDefinition;
|
||||||
|
|
||||||
public PEDefinitionTypeSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition) {
|
public PEDefinitionTypeSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition, String ppath) {
|
||||||
super(builder, name, profile, definition);
|
super(builder, name, profile, definition, ppath);
|
||||||
this.sliceDefinition = sliceDefinition;
|
this.sliceDefinition = sliceDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -236,4 +236,8 @@ public class PEInstance {
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Base getBase() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
package org.hl7.fhir.r5.profilemodel.gen;
|
package org.hl7.fhir.r5.profilemodel.gen;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEInstance;
|
import org.hl7.fhir.r5.profilemodel.PEInstance;
|
||||||
|
|
||||||
public class PEGeneratedBase {
|
public class PEGeneratedBase {
|
||||||
|
|
||||||
protected PEInstance instance;
|
protected PEInstance instance;
|
||||||
|
|
||||||
protected void removeChild(String string) {
|
protected void removeChild(String name) {
|
||||||
PEInstance child = instance.child("simple");
|
PEInstance child = instance.child(name);
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
instance.removeChild(child);
|
instance.removeChild(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void removeChildren(String name) {
|
||||||
|
for (PEInstance child : instance.children(name)) {
|
||||||
|
instance.removeChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PEInstance getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Base getData() {
|
||||||
|
return instance.getBase();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package org.hl7.fhir.r5.profilemodel.gen;
|
package org.hl7.fhir.r5.profilemodel.gen;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.model.CodeType;
|
import org.hl7.fhir.r5.model.CodeType;
|
||||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
|
@ -60,37 +63,103 @@ public class ProfileExample extends PEGeneratedBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ProfileExampleComplexSlice3 extends PEGeneratedBase {
|
||||||
|
private ProfileExampleComplexSlice3(PEInstance instance) {
|
||||||
|
super();
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Coding> getSlice3a() {
|
||||||
|
List<Coding> res = new ArrayList<>();
|
||||||
|
for (PEInstance pe : instance.children("slice3a")) {
|
||||||
|
res.add((Coding) pe.asDataType());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSlice3a() {
|
||||||
|
return instance.children("slice3a").size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileExampleComplexSlice3 clearSlice3a() {
|
||||||
|
removeChildren("slice3a");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<StringType> getSlice3b() {
|
||||||
|
List<StringType> res = new ArrayList<>();
|
||||||
|
for (PEInstance pe : instance.children("slice3b")) {
|
||||||
|
res.add((StringType) pe.asDataType());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSlice3b() {
|
||||||
|
return instance.children("slice3b").size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileExampleComplexSlice3 clearSlice3b() {
|
||||||
|
removeChildren("slice3b");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ProfileExampleComplex extends PEGeneratedBase {
|
public static class ProfileExampleComplex extends PEGeneratedBase {
|
||||||
private ProfileExampleComplex(PEInstance instance) {
|
private ProfileExampleComplex(PEInstance instance) {
|
||||||
super();
|
super();
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coding getSlice1() {
|
public List<Coding> getSlice1() {
|
||||||
return (Coding) instance.forceChild("slice1").asDataType();
|
List<Coding> res = new ArrayList<>();
|
||||||
|
for (PEInstance pe : instance.children("slice1")) {
|
||||||
|
res.add((Coding) pe.asDataType());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSlice1() {
|
public boolean hasSlice1() {
|
||||||
return instance.child("slice1") != null;
|
return instance.children("slice1").size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileExampleComplex clearSlice1() {
|
public ProfileExampleComplex clearSlice1() {
|
||||||
removeChild("slice1x`");
|
removeChildren("slice1");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringType getSlice2() {
|
public List<StringType> getSlice2() {
|
||||||
return (StringType) instance.forceChild("slice2").asDataType();
|
List<StringType> res = new ArrayList<>();
|
||||||
|
for (PEInstance pe : instance.children("slice2")) {
|
||||||
|
res.add((StringType) pe.asDataType());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSlice2() {
|
public boolean hasSlice2() {
|
||||||
return instance.child("slice1") != null;
|
return instance.children("slice2").size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileExampleComplex clearSlice2() {
|
public ProfileExampleComplex clearSlice2() {
|
||||||
removeChild("slice1");
|
removeChildren("slice1");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProfileExampleComplexSlice3 getSlice3() {
|
||||||
|
PEInstance pe = instance.forceChild("slice3");
|
||||||
|
return new ProfileExampleComplexSlice3(pe);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasComplex() {
|
||||||
|
return instance.child("slice3") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileExampleComplex clearComplex() {
|
||||||
|
removeChild("slice3");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileExample(IWorkerContext context, Observation observation) {
|
public ProfileExample(IWorkerContext context, Observation observation) {
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.hl7.fhir.r5.renderers;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
|
||||||
|
public interface CodeResolver {
|
||||||
|
|
||||||
|
public class CodeResolution {
|
||||||
|
private String systenName;
|
||||||
|
private String systemLink;
|
||||||
|
private String link;
|
||||||
|
private String display;
|
||||||
|
private String hint;
|
||||||
|
|
||||||
|
|
||||||
|
protected CodeResolution(String systenName, String systemLink, String link, String display, String hint) {
|
||||||
|
super();
|
||||||
|
this.systenName = systenName;
|
||||||
|
this.systemLink = systemLink;
|
||||||
|
this.link = link;
|
||||||
|
this.display = display;
|
||||||
|
this.hint = hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSystenName() {
|
||||||
|
return systenName;
|
||||||
|
}
|
||||||
|
public String getSystemLink() {
|
||||||
|
return systemLink;
|
||||||
|
}
|
||||||
|
public String getLink() {
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
public String getDisplay() {
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
public String getHint() {
|
||||||
|
return hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeResolution resolveCode(String system, String code);
|
||||||
|
public CodeResolution resolveCode(Coding code);
|
||||||
|
public CodeResolution resolveCode(CodeableConcept code);
|
||||||
|
}
|
|
@ -15,7 +15,6 @@ import java.time.format.FormatStyle;
|
||||||
import java.time.format.SignStyle;
|
import java.time.format.SignStyle;
|
||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
@ -71,9 +70,11 @@ import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||||
|
import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
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.GenerationRules;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
|
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
@ -85,7 +86,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||||
|
|
||||||
public class DataRenderer extends Renderer {
|
public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
|
|
||||||
// -- 1. context --------------------------------------------------------------
|
// -- 1. context --------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -302,6 +303,9 @@ public class DataRenderer extends Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String lookupCode(String system, String version, String code) {
|
private String lookupCode(String system, String version, String code) {
|
||||||
|
if (JurisdictionUtilities.isJurisdiction(system)) {
|
||||||
|
return JurisdictionUtilities.displayJurisdiction(system+"#"+code);
|
||||||
|
}
|
||||||
ValidationResult t = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions().setVersionFlexible(true), system, version, code, null);
|
ValidationResult t = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions().setVersionFlexible(true), system, version, code, null);
|
||||||
|
|
||||||
if (t != null && t.getDisplay() != null)
|
if (t != null && t.getDisplay() != null)
|
||||||
|
@ -948,6 +952,12 @@ public class DataRenderer extends Renderer {
|
||||||
} else {
|
} else {
|
||||||
return "https://www.nlm.nih.gov/research/umls/rxnorm/index.html";
|
return "https://www.nlm.nih.gov/research/umls/rxnorm/index.html";
|
||||||
}
|
}
|
||||||
|
} else if ("urn:iso:std:iso:3166".equals(system)) {
|
||||||
|
if (!Utilities.noString(code)) {
|
||||||
|
return "https://en.wikipedia.org/wiki/ISO_3166-2:"+code;
|
||||||
|
} else {
|
||||||
|
return "https://en.wikipedia.org/wiki/ISO_3166-2";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
CodeSystem cs = context.getWorker().fetchCodeSystem(system, version);
|
CodeSystem cs = context.getWorker().fetchCodeSystem(system, version);
|
||||||
if (cs != null && cs.hasUserData("path")) {
|
if (cs != null && cs.hasUserData("path")) {
|
||||||
|
@ -961,6 +971,41 @@ public class DataRenderer extends Renderer {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CodeResolution resolveCode(String system, String code) {
|
||||||
|
return resolveCode(new Coding().setSystem(system).setCode(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeResolution resolveCode(Coding c) {
|
||||||
|
String systemName;
|
||||||
|
String systemLink;
|
||||||
|
String link;
|
||||||
|
String display = null;
|
||||||
|
String hint;
|
||||||
|
|
||||||
|
if (c.hasDisplayElement())
|
||||||
|
display = c.getDisplay();
|
||||||
|
if (Utilities.noString(display))
|
||||||
|
display = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||||
|
if (Utilities.noString(display)) {
|
||||||
|
display = c.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeSystem cs = context.getWorker().fetchCodeSystem(c.getSystem());
|
||||||
|
systemLink = cs != null ? cs.getUserString("path") : null;
|
||||||
|
systemName = cs != null ? cs.present() : describeSystem(c.getSystem());
|
||||||
|
link = getLinkForCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||||
|
|
||||||
|
hint = systemName+": "+display+(c.hasVersion() ? " (version = "+c.getVersion()+")" : "");
|
||||||
|
return new CodeResolution(systemName, systemLink, link, display, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeResolution resolveCode(CodeableConcept code) {
|
||||||
|
if (code.hasCoding()) {
|
||||||
|
return resolveCode(code.getCodingFirstRep());
|
||||||
|
} else {
|
||||||
|
return new CodeResolution(null, null, null, code.getText(), code.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
protected void renderCodingWithDetails(XhtmlNode x, Coding c) {
|
protected void renderCodingWithDetails(XhtmlNode x, Coding c) {
|
||||||
String s = "";
|
String s = "";
|
||||||
if (c.hasDisplayElement())
|
if (c.hasDisplayElement())
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
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.GenerationRules;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
|
import org.hl7.fhir.r5.utils.TranslatingUtilities;
|
||||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
|
@ -25,7 +26,7 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
* @author graha
|
* @author graha
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Renderer {
|
public class Renderer extends TranslatingUtilities {
|
||||||
|
|
||||||
protected RenderingContext context;
|
protected RenderingContext context;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.hl7.fhir.r5.model.DomainResource;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
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;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
|
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@ package org.hl7.fhir.r5.renderers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
|
||||||
import org.hl7.fhir.r5.model.ActorDefinition;
|
import org.hl7.fhir.r5.model.ActorDefinition;
|
||||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
import org.hl7.fhir.r5.model.CanonicalType;
|
import org.hl7.fhir.r5.model.CanonicalType;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,8 +11,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.elementmodel.Element;
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
@ -74,6 +74,12 @@ public class RenderingContext {
|
||||||
IG_PUBLISHER
|
IG_PUBLISHER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum StructureDefinitionRendererMode {
|
||||||
|
SUMMARY, // 5 cells: tree/name | flags | cardinality | type | details
|
||||||
|
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 QuestionnaireRendererMode {
|
public enum QuestionnaireRendererMode {
|
||||||
/**
|
/**
|
||||||
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
|
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
|
||||||
|
@ -139,6 +145,8 @@ public class RenderingContext {
|
||||||
private boolean inlineGraphics;
|
private boolean inlineGraphics;
|
||||||
|
|
||||||
private QuestionnaireRendererMode questionnaireMode = QuestionnaireRendererMode.FORM;
|
private QuestionnaireRendererMode questionnaireMode = QuestionnaireRendererMode.FORM;
|
||||||
|
private StructureDefinitionRendererMode structureMode = StructureDefinitionRendererMode.SUMMARY;
|
||||||
|
|
||||||
private boolean addGeneratedNarrativeHeader = true;
|
private boolean addGeneratedNarrativeHeader = true;
|
||||||
private boolean showComments = false;
|
private boolean showComments = false;
|
||||||
|
|
||||||
|
@ -201,6 +209,7 @@ public class RenderingContext {
|
||||||
res.destDir = destDir;
|
res.destDir = destDir;
|
||||||
res.addGeneratedNarrativeHeader = addGeneratedNarrativeHeader;
|
res.addGeneratedNarrativeHeader = addGeneratedNarrativeHeader;
|
||||||
res.questionnaireMode = questionnaireMode;
|
res.questionnaireMode = questionnaireMode;
|
||||||
|
res.structureMode = structureMode;
|
||||||
res.header = header;
|
res.header = header;
|
||||||
res.links.putAll(links);
|
res.links.putAll(links);
|
||||||
res.inlineGraphics = inlineGraphics;
|
res.inlineGraphics = inlineGraphics;
|
||||||
|
@ -356,6 +365,9 @@ public class RenderingContext {
|
||||||
|
|
||||||
public RenderingContext setProfileUtilities(ProfileUtilities profileUtilities) {
|
public RenderingContext setProfileUtilities(ProfileUtilities profileUtilities) {
|
||||||
this.profileUtilitiesR = profileUtilities;
|
this.profileUtilitiesR = profileUtilities;
|
||||||
|
if (pkp == null && profileUtilities.getPkp() != null) {
|
||||||
|
pkp = profileUtilities.getPkp();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,6 +445,15 @@ public class RenderingContext {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StructureDefinitionRendererMode getStructureMode() {
|
||||||
|
return structureMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderingContext setStructureMode(StructureDefinitionRendererMode structureMode) {
|
||||||
|
this.structureMode = structureMode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public String fixReference(String ref) {
|
public String fixReference(String ref) {
|
||||||
if (!Utilities.isAbsoluteUrl(ref)) {
|
if (!Utilities.isAbsoluteUrl(ref)) {
|
||||||
return (localPrefix == null ? "" : localPrefix)+ref;
|
return (localPrefix == null ? "" : localPrefix)+ref;
|
||||||
|
|
|
@ -5996,5 +5996,9 @@ public class JurisdictionUtilities {
|
||||||
}
|
}
|
||||||
return "Unknown region code '"+c.getCode()+"'";
|
return "Unknown region code '"+c.getCode()+"'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isJurisdiction(String system) {
|
||||||
|
return Utilities.existsInList(system, "http://unstats.un.org/unsd/methods/m49/m49.htm", "urn:iso:std:iso:3166", "urn:iso:std:iso:3166:-2");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class TestPackageLoader implements IContextResourceLoader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getResourcePath(Resource resource) {
|
public String getResourcePath(Resource resource) {
|
||||||
return null;
|
return resource.fhirType().toLowerCase()+"-"+resource.getId()+".html";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,8 +36,8 @@ package org.hl7.fhir.r5.utils.structuremap;
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hl7.fhir.r5.profilemodel.PEType;
|
||||||
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample;
|
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample;
|
||||||
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.LOINCCodesForCholesterolInSerumPlasma;
|
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.LOINCCodesForCholesterolInSerumPlasma;
|
||||||
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.ProfileExampleComplex;
|
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.ProfileExampleComplex;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.ProfileExampleComplexSlice3;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEBuilder;
|
import org.hl7.fhir.r5.profilemodel.PEBuilder;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
|
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEInstance.PEInstanceDataKind;
|
import org.hl7.fhir.r5.profilemodel.PEInstance.PEInstanceDataKind;
|
||||||
|
@ -105,7 +106,7 @@ public class PETests {
|
||||||
checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||||
checkElement(gchildren.get(1), "extension", "slice1", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice1').value");
|
checkElement(gchildren.get(1), "extension", "slice1", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice1').value");
|
||||||
checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice2').value");
|
checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice2').value");
|
||||||
checkElement(gchildren.get(3), "extension", "slice3", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension('slice3').extension");
|
checkElement(gchildren.get(3), "extension", "slice3", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension('slice3')");
|
||||||
|
|
||||||
ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
||||||
checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||||
|
@ -351,14 +352,21 @@ public class PETests {
|
||||||
Assertions.assertEquals(PEInstanceDataKind.Primitive, slice2.getDataKind());
|
Assertions.assertEquals(PEInstanceDataKind.Primitive, slice2.getDataKind());
|
||||||
Assertions.assertEquals("A string value", slice2.getPrimitiveAsString());
|
Assertions.assertEquals("A string value", slice2.getPrimitiveAsString());
|
||||||
|
|
||||||
|
PEInstance slice3 = complex.child("slice3");
|
||||||
|
Assertions.assertNotNull(slice3);
|
||||||
|
Assertions.assertEquals("TestProfile.complex.slice3", slice3.getPath());
|
||||||
|
|
||||||
ProfileExample ex = new ProfileExample(obs);
|
ProfileExample ex = new ProfileExample(obs);
|
||||||
Assertions.assertEquals(ObservationStatus.FINAL, ex.getStatus());
|
Assertions.assertEquals(ObservationStatus.FINAL, ex.getStatus());
|
||||||
Assertions.assertEquals("76690-7", ex.getCode().getCodingFirstRep().getCode());
|
Assertions.assertEquals("76690-7", ex.getCode().getCodingFirstRep().getCode());
|
||||||
Assertions.assertEquals(LOINCCodesForCholesterolInSerumPlasma.L14647_2, ex.getSimple());
|
Assertions.assertEquals(LOINCCodesForCholesterolInSerumPlasma.L14647_2, ex.getSimple());
|
||||||
ProfileExampleComplex cplx = ex.getComplex();
|
ProfileExampleComplex cplx = ex.getComplex();
|
||||||
Assertions.assertNotNull(cplx);
|
Assertions.assertNotNull(cplx);
|
||||||
Assertions.assertEquals("18767-4", cplx.getSlice1().getCode());
|
Assertions.assertEquals("18767-4", cplx.getSlice1().get(0).getCode());
|
||||||
Assertions.assertEquals("A string value", cplx.getSlice2().primitiveValue());
|
Assertions.assertEquals("A string value", cplx.getSlice2().get(0).primitiveValue());
|
||||||
|
ProfileExampleComplexSlice3 sl3 = cplx.getSlice3();
|
||||||
|
Assertions.assertEquals("56874-1", sl3.getSlice3a().get(0).getCode());
|
||||||
|
Assertions.assertEquals("Another string value", sl3.getSlice3b().get(0).primitiveValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.BindingResolution;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||||
|
@ -22,17 +23,22 @@ import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
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.RendererFactory;
|
||||||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
|
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
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.GenerationRules;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.StructureDefinitionRendererMode;
|
||||||
import org.hl7.fhir.r5.test.utils.CompareUtilities;
|
import org.hl7.fhir.r5.test.utils.CompareUtilities;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestPackageLoader;
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
@ -86,6 +92,14 @@ public class NarrativeGenerationTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException {
|
public BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException {
|
||||||
|
ValueSet vs = context.fetchResource(ValueSet.class, url);
|
||||||
|
if (vs != null) {
|
||||||
|
if (vs.hasUserData("path")) {
|
||||||
|
return new BindingResolution(vs.present(), vs.getUserString("path"));
|
||||||
|
} else {
|
||||||
|
return new BindingResolution(vs.present(), "valueset-"+vs.getIdBase()+".html");
|
||||||
|
}
|
||||||
|
}
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +113,7 @@ public class NarrativeGenerationTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean prependLinks() {
|
public boolean prependLinks() {
|
||||||
throw new NotImplementedException();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -137,13 +151,23 @@ public class NarrativeGenerationTests {
|
||||||
|
|
||||||
public static class TestDetails {
|
public static class TestDetails {
|
||||||
private String id;
|
private String id;
|
||||||
|
private String sdmode;
|
||||||
private boolean header;
|
private boolean header;
|
||||||
private boolean meta;
|
private boolean meta;
|
||||||
private boolean technical;
|
private boolean technical;
|
||||||
|
private String register;
|
||||||
|
|
||||||
public TestDetails(Element test) {
|
public TestDetails(Element test) {
|
||||||
super();
|
super();
|
||||||
id = test.getAttribute("id");
|
id = test.getAttribute("id");
|
||||||
|
sdmode = test.getAttribute("sdmode");
|
||||||
|
if ("".equals(sdmode)) {
|
||||||
|
sdmode = null;
|
||||||
|
}
|
||||||
|
register = test.getAttribute("register");
|
||||||
|
if ("".equals(register)) {
|
||||||
|
register = null;
|
||||||
|
}
|
||||||
header = "true".equals(test.getAttribute("header"));
|
header = "true".equals(test.getAttribute("header"));
|
||||||
meta = "true".equals(test.getAttribute("meta"));
|
meta = "true".equals(test.getAttribute("meta"));
|
||||||
technical = "technical".equals(test.getAttribute("mode"));
|
technical = "technical".equals(test.getAttribute("mode"));
|
||||||
|
@ -153,6 +177,10 @@ public class NarrativeGenerationTests {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSDMode() {
|
||||||
|
return sdmode;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isHeader() {
|
public boolean isHeader() {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +189,10 @@ public class NarrativeGenerationTests {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRegister() {
|
||||||
|
return register;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
||||||
|
@ -176,13 +208,23 @@ public class NarrativeGenerationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void setUp() {
|
public static void setUp() throws IOException {
|
||||||
context = TestingUtilities.getSharedWorkerContext("5.0.0");
|
context = TestingUtilities.getSharedWorkerContext("5.0.0");
|
||||||
|
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true);
|
||||||
|
NpmPackage ips = pcm.loadPackage("hl7.fhir.uv.ips#1.1.0");
|
||||||
|
context.loadFromPackage(ips, new TestPackageLoader(new String[] { "StructureDefinition", "ValueSet" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{index}: file {0}")
|
@ParameterizedTest(name = "{index}: file {0}")
|
||||||
@MethodSource("data")
|
@MethodSource("data")
|
||||||
public void test(String id, TestDetails test) throws Exception {
|
public void test(String id, TestDetails test) throws Exception {
|
||||||
|
if (test.getRegister() != null) {
|
||||||
|
if (test.getRegister().endsWith(".json")) {
|
||||||
|
context.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getRegister())));
|
||||||
|
} else {
|
||||||
|
context.cacheResource(new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getRegister())));
|
||||||
|
}
|
||||||
|
}
|
||||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER, GenerationRules.VALID_RESOURCE);
|
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER, GenerationRules.VALID_RESOURCE);
|
||||||
rc.setDestDir(Utilities.path("[tmp]", "narrative"));
|
rc.setDestDir(Utilities.path("[tmp]", "narrative"));
|
||||||
rc.setHeader(test.isHeader());
|
rc.setHeader(test.isHeader());
|
||||||
|
@ -198,6 +240,9 @@ public class NarrativeGenerationTests {
|
||||||
rc.setMode(test.technical ? ResourceRendererMode.TECHNICAL : ResourceRendererMode.END_USER);
|
rc.setMode(test.technical ? ResourceRendererMode.TECHNICAL : ResourceRendererMode.END_USER);
|
||||||
rc.setProfileUtilities(new ProfileUtilities(rc.getContext(), null, new TestProfileKnowledgeProvider(rc.getContext())));
|
rc.setProfileUtilities(new ProfileUtilities(rc.getContext(), null, new TestProfileKnowledgeProvider(rc.getContext())));
|
||||||
|
|
||||||
|
if (test.getSDMode() != null) {
|
||||||
|
rc.setStructureMode(StructureDefinitionRendererMode.valueOf(test.getSDMode().toUpperCase()));
|
||||||
|
}
|
||||||
|
|
||||||
Resource source;
|
Resource source;
|
||||||
if (TestingUtilities.findTestResource("r5", "narrative", test.getId() + ".json")) {
|
if (TestingUtilities.findTestResource("r5", "narrative", test.getId() + ".json")) {
|
||||||
|
@ -208,7 +253,7 @@ public class NarrativeGenerationTests {
|
||||||
|
|
||||||
XhtmlNode x = RendererFactory.factory(source, rc).build(source);
|
XhtmlNode x = RendererFactory.factory(source, rc).build(source);
|
||||||
String expected = TextFile.streamToString(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + ".html"));
|
String expected = TextFile.streamToString(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + ".html"));
|
||||||
String actual = HEADER+new XhtmlComposer(true, true).compose(x)+FOOTER;
|
String actual = HEADER+new XhtmlComposer(true, false).compose(x)+FOOTER;
|
||||||
String expectedFileName = CompareUtilities.tempFile("narrative", test.getId() + ".expected.html");
|
String expectedFileName = CompareUtilities.tempFile("narrative", test.getId() + ".expected.html");
|
||||||
String actualFileName = CompareUtilities.tempFile("narrative", test.getId() + ".actual.html");
|
String actualFileName = CompareUtilities.tempFile("narrative", test.getId() + ".actual.html");
|
||||||
TextFile.stringToFile(expected, expectedFileName);
|
TextFile.stringToFile(expected, expectedFileName);
|
||||||
|
|
|
@ -17,8 +17,9 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.r5.DiffUtils;
|
import org.hl7.fhir.r5.DiffUtils;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.BindingResolution;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.test.utils.TestPackageLoader;
|
import org.hl7.fhir.r5.test.utils.TestPackageLoader;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "urn:iso:std:iso:3166",
|
||||||
|
"code" : "BE"
|
||||||
|
}, "valueSet" :null, "lang":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"true"}####
|
||||||
|
v: {
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "Local Error: Resolved system urn:iso:std:iso:3166 (v1.0.0), but the definition is not complete. Server Error: Attempt to use Terminology server when no Terminology server is available",
|
||||||
|
"class" : "SERVER_ERROR"
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
|
@ -134,7 +134,7 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
||||||
private String hint;
|
private String hint;
|
||||||
private String style;
|
private String style;
|
||||||
private Map<String, String> attributes;
|
private Map<String, String> attributes;
|
||||||
private List<XhtmlNode> children;
|
private XhtmlNodeList children;
|
||||||
|
|
||||||
public Piece(String tag) {
|
public Piece(String tag) {
|
||||||
super();
|
super();
|
||||||
|
@ -205,9 +205,9 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
||||||
return children != null && !children.isEmpty();
|
return children != null && !children.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<XhtmlNode> getChildren() {
|
public XhtmlNodeList getChildren() {
|
||||||
if (children == null)
|
if (children == null)
|
||||||
children = new ArrayList<XhtmlNode>();
|
children = new XhtmlNodeList();
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,8 +853,9 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
||||||
} else if (p.getStyle() != null) {
|
} else if (p.getStyle() != null) {
|
||||||
XhtmlNode s = addStyle(tc.addTag("span"), p);
|
XhtmlNode s = addStyle(tc.addTag("span"), p);
|
||||||
s.addText(p.getText());
|
s.addText(p.getText());
|
||||||
} else
|
} else {
|
||||||
tc.addText(p.getText());
|
tc.addText(p.getText());
|
||||||
|
}
|
||||||
if (p.hasChildren()) {
|
if (p.hasChildren()) {
|
||||||
tc.getChildNodes().addAll(p.getChildren());
|
tc.getChildNodes().addAll(p.getChildren());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
package org.hl7.fhir.utilities.xhtml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||||
|
|
||||||
|
public abstract class XhtmlFluent {
|
||||||
|
|
||||||
|
protected abstract XhtmlNode addTag(String string);
|
||||||
|
protected abstract XhtmlNode addText(String cnt);
|
||||||
|
protected abstract void addChildren(XhtmlNodeList childNodes);
|
||||||
|
|
||||||
|
public XhtmlNode h1() {
|
||||||
|
return addTag("h1");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XhtmlNode h2() {
|
||||||
|
return addTag("h2");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode h(int level) {
|
||||||
|
if (level < 1 || level > 6) {
|
||||||
|
throw new FHIRException("Illegal Header level "+level);
|
||||||
|
}
|
||||||
|
return addTag("h"+Integer.toString(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode h3() {
|
||||||
|
return addTag("h3");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode h4() {
|
||||||
|
return addTag("h4");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode table(String clss) {
|
||||||
|
XhtmlNode res = addTag("table");
|
||||||
|
if (!Utilities.noString(clss))
|
||||||
|
res.setAttribute("class", clss);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode tr() {
|
||||||
|
return addTag("tr");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode th() {
|
||||||
|
return addTag("th");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode td() {
|
||||||
|
return addTag("td");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode td(String clss) {
|
||||||
|
return addTag("td").attribute("class", clss);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode div() {
|
||||||
|
return addTag("div");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode para() {
|
||||||
|
return addTag("p");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode pre() {
|
||||||
|
return addTag("pre");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode pre(String clss) {
|
||||||
|
return addTag("pre").setAttribute("class", clss);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void br() {
|
||||||
|
addTag("br");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hr() {
|
||||||
|
addTag("hr");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode ul() {
|
||||||
|
return addTag("ul");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode li() {
|
||||||
|
return addTag("li");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode b() {
|
||||||
|
return addTag("b");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode i() {
|
||||||
|
return addTag("i");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode tx(String cnt) {
|
||||||
|
return addText(cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode tx(int cnt) {
|
||||||
|
return addText(Integer.toString(cnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode ah(String href) {
|
||||||
|
return addTag("a").attribute("href", href);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode ah(String href, String title) {
|
||||||
|
XhtmlNode x = addTag("a").attribute("href", href);
|
||||||
|
if (title != null) {
|
||||||
|
x.attribute("title", title);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode img(String src, String alt) {
|
||||||
|
return addTag("img").attribute("src", src).attribute("alt", alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode img(String src, String alt, String title) {
|
||||||
|
return addTag("img").attribute("src", src).attribute("alt", alt).attribute("title", title);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode an(String href) {
|
||||||
|
return an(href, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode an(String href, String tx) {
|
||||||
|
XhtmlNode a = addTag("a").attribute("name", href);
|
||||||
|
a.tx(tx);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode span(String style, String title) {
|
||||||
|
XhtmlNode res = addTag("span");
|
||||||
|
if (!Utilities.noString(style))
|
||||||
|
res.attribute("style", style);
|
||||||
|
if (!Utilities.noString(title))
|
||||||
|
res.attribute("title", title);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XhtmlNode code(String text) {
|
||||||
|
return addTag("code").tx(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode code() {
|
||||||
|
return addTag("code");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XhtmlNode blockquote() {
|
||||||
|
return addTag("blockquote");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void markdown(String md, String source) throws IOException {
|
||||||
|
if (md != null) {
|
||||||
|
String s = new MarkDownProcessor(Dialect.COMMON_MARK).process(md, source);
|
||||||
|
XhtmlParser p = new XhtmlParser();
|
||||||
|
XhtmlNode m;
|
||||||
|
try {
|
||||||
|
m = p.parse("<div>"+s+"</div>", "div");
|
||||||
|
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
||||||
|
throw new FHIRFormatError(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
addChildren(m.getChildNodes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void innerHTML(String html) throws IOException {
|
||||||
|
if (html != null) {
|
||||||
|
XhtmlParser p = new XhtmlParser();
|
||||||
|
XhtmlNode m;
|
||||||
|
try {
|
||||||
|
m = p.parse("<div>"+html+"</div>", "div");
|
||||||
|
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
||||||
|
throw new FHIRFormatError(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
addChildren(m.getChildNodes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -35,7 +35,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -50,7 +49,7 @@ import org.hl7.fhir.utilities.Utilities;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
|
|
||||||
@ca.uhn.fhir.model.api.annotation.DatatypeDef(name="xhtml")
|
@ca.uhn.fhir.model.api.annotation.DatatypeDef(name="xhtml")
|
||||||
public class XhtmlNode implements IBaseXhtml {
|
public class XhtmlNode extends XhtmlFluent implements IBaseXhtml {
|
||||||
private static final long serialVersionUID = -4362547161441436492L;
|
private static final long serialVersionUID = -4362547161441436492L;
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,11 +82,9 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
private NodeType nodeType;
|
private NodeType nodeType;
|
||||||
private String name;
|
private String name;
|
||||||
private Map<String, String> attributes = new HashMap<String, String>();
|
private Map<String, String> attributes = new HashMap<String, String>();
|
||||||
private List<XhtmlNode> childNodes = new ArrayList<XhtmlNode>();
|
private XhtmlNodeList childNodes = new XhtmlNodeList();
|
||||||
private String content;
|
private String content;
|
||||||
private boolean notPretty;
|
private boolean notPretty;
|
||||||
private boolean inPara;
|
|
||||||
private boolean inLink;
|
|
||||||
private boolean seperated;
|
private boolean seperated;
|
||||||
private Boolean emptyExpanded;
|
private Boolean emptyExpanded;
|
||||||
|
|
||||||
|
@ -129,7 +126,7 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<XhtmlNode> getChildNodes() {
|
public XhtmlNodeList getChildNodes() {
|
||||||
return childNodes;
|
return childNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,11 +202,11 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
// }
|
// }
|
||||||
XhtmlNode node = new XhtmlNode(NodeType.Element);
|
XhtmlNode node = new XhtmlNode(NodeType.Element);
|
||||||
node.setName(name);
|
node.setName(name);
|
||||||
if (inPara || name.equals("p")) {
|
if (childNodes.isInPara() || name.equals("p")) {
|
||||||
node.inPara = true;
|
node.getChildNodes().setInPara(true);
|
||||||
}
|
}
|
||||||
if (inLink || name.equals("a")) {
|
if (childNodes.isInLink() || name.equals("a")) {
|
||||||
node.inLink = true;
|
node.getChildNodes().setInLink(true);
|
||||||
}
|
}
|
||||||
childNodes.add(node);
|
childNodes.add(node);
|
||||||
return node;
|
return node;
|
||||||
|
@ -221,11 +218,11 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
|
if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
|
||||||
throw new Error("Wrong node type. is "+nodeType.toString());
|
throw new Error("Wrong node type. is "+nodeType.toString());
|
||||||
XhtmlNode node = new XhtmlNode(NodeType.Element);
|
XhtmlNode node = new XhtmlNode(NodeType.Element);
|
||||||
if (inPara || name.equals("p")) {
|
if (childNodes.isInPara() || name.equals("p")) {
|
||||||
node.inPara = true;
|
node.getChildNodes().setInPara(true);
|
||||||
}
|
}
|
||||||
if (inLink || name.equals("a")) {
|
if (childNodes.isInLink() || name.equals("a")) {
|
||||||
node.inLink = true;
|
node.getChildNodes().setInLink(true);
|
||||||
}
|
}
|
||||||
node.setName(name);
|
node.setName(name);
|
||||||
childNodes.add(index, node);
|
childNodes.add(index, node);
|
||||||
|
@ -554,158 +551,6 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
}
|
}
|
||||||
|
|
||||||
// xhtml easy adders -----------------------------------------------
|
// xhtml easy adders -----------------------------------------------
|
||||||
public XhtmlNode h1() {
|
|
||||||
return addTag("h1");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode h2() {
|
|
||||||
return addTag("h2");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode h(int level) {
|
|
||||||
if (level < 1 || level > 6) {
|
|
||||||
throw new FHIRException("Illegal Header level "+level);
|
|
||||||
}
|
|
||||||
return addTag("h"+Integer.toString(level));
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode h3() {
|
|
||||||
return addTag("h3");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode h4() {
|
|
||||||
return addTag("h4");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode table(String clss) {
|
|
||||||
XhtmlNode res = addTag("table");
|
|
||||||
if (!Utilities.noString(clss))
|
|
||||||
res.setAttribute("class", clss);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode tr() {
|
|
||||||
return addTag("tr");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode th() {
|
|
||||||
return addTag("th");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode td() {
|
|
||||||
return addTag("td");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode td(String clss) {
|
|
||||||
return addTag("td").attribute("class", clss);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode colspan(String n) {
|
|
||||||
return setAttribute("colspan", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode div() {
|
|
||||||
return addTag("div");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode para() {
|
|
||||||
return addTag("p");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode pre() {
|
|
||||||
return addTag("pre");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode pre(String clss) {
|
|
||||||
return addTag("pre").setAttribute("class", clss);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void br() {
|
|
||||||
addTag("br");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hr() {
|
|
||||||
addTag("hr");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode ul() {
|
|
||||||
return addTag("ul");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode li() {
|
|
||||||
return addTag("li");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode b() {
|
|
||||||
return addTag("b");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode i() {
|
|
||||||
return addTag("i");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode tx(String cnt) {
|
|
||||||
return addText(cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// differs from tx because it returns the owner node, not the created text
|
|
||||||
public XhtmlNode txN(String cnt) {
|
|
||||||
addText(cnt);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode tx(int cnt) {
|
|
||||||
return addText(Integer.toString(cnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode ah(String href) {
|
|
||||||
return addTag("a").attribute("href", href);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode ah(String href, String title) {
|
|
||||||
return addTag("a").attribute("href", href).attribute("title", title);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode img(String src, String alt) {
|
|
||||||
return addTag("img").attribute("src", src).attribute("alt", alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode img(String src, String alt, String title) {
|
|
||||||
return addTag("img").attribute("src", src).attribute("alt", alt).attribute("title", title);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode an(String href) {
|
|
||||||
return an(href, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode an(String href, String tx) {
|
|
||||||
XhtmlNode a = addTag("a").attribute("name", href);
|
|
||||||
a.tx(tx);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode span(String style, String title) {
|
|
||||||
XhtmlNode res = addTag("span");
|
|
||||||
if (!Utilities.noString(style))
|
|
||||||
res.attribute("style", style);
|
|
||||||
if (!Utilities.noString(title))
|
|
||||||
res.attribute("title", title);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public XhtmlNode code(String text) {
|
|
||||||
return addTag("code").tx(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XhtmlNode code() {
|
|
||||||
return addTag("code");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public XhtmlNode blockquote() {
|
|
||||||
return addTag("blockquote");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -847,36 +692,6 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
return "p".equals(name);
|
return "p".equals(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void markdown(String md, String source) throws IOException {
|
|
||||||
if (md != null) {
|
|
||||||
String s = new MarkDownProcessor(Dialect.COMMON_MARK).process(md, source);
|
|
||||||
XhtmlParser p = new XhtmlParser();
|
|
||||||
XhtmlNode m;
|
|
||||||
try {
|
|
||||||
m = p.parse("<div>"+s+"</div>", "div");
|
|
||||||
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
|
||||||
throw new FHIRFormatError(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
getChildNodes().addAll(m.getChildNodes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void innerHTML(String html) throws IOException {
|
|
||||||
if (html != null) {
|
|
||||||
XhtmlParser p = new XhtmlParser();
|
|
||||||
XhtmlNode m;
|
|
||||||
try {
|
|
||||||
m = p.parse("<div>"+html+"</div>", "div");
|
|
||||||
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
|
||||||
throw new FHIRFormatError(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
getChildNodes().addAll(m.getChildNodes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public XhtmlNode sep(String separator) {
|
public XhtmlNode sep(String separator) {
|
||||||
// if there's already text, add the separator. otherwise, we'll add it next time
|
// if there's already text, add the separator. otherwise, we'll add it next time
|
||||||
if (!seperated) {
|
if (!seperated) {
|
||||||
|
@ -887,8 +702,23 @@ public class XhtmlNode implements IBaseXhtml {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// more fluent
|
||||||
|
|
||||||
|
public XhtmlNode colspan(String n) {
|
||||||
|
return setAttribute("colspan", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// differs from tx because it returns the owner node, not the created text
|
||||||
|
public XhtmlNode txN(String cnt) {
|
||||||
|
addText(cnt);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addChildren(XhtmlNodeList childNodes) {
|
||||||
|
this.childNodes.addAll(childNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
package org.hl7.fhir.utilities.xhtml;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
public class XhtmlNodeList extends XhtmlFluent implements List<XhtmlNode>, java.io.Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private List<XhtmlNode> list = new ArrayList<>();
|
||||||
|
private boolean inPara;
|
||||||
|
private boolean inLink;
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isInPara() {
|
||||||
|
return inPara;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInPara(boolean inPara) {
|
||||||
|
this.inPara = inPara;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInLink() {
|
||||||
|
return inLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInLink(boolean inLink) {
|
||||||
|
this.inLink = inLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XhtmlNode addTag(String name)
|
||||||
|
{
|
||||||
|
|
||||||
|
// if (inPara && name.equals("p")) {
|
||||||
|
// throw new FHIRException("nested Para");
|
||||||
|
// }
|
||||||
|
// if (inLink && name.equals("a")) {
|
||||||
|
// throw new FHIRException("Nested Link");
|
||||||
|
// }
|
||||||
|
XhtmlNode node = new XhtmlNode(NodeType.Element);
|
||||||
|
node.setName(name);
|
||||||
|
if (isInPara() || name.equals("p")) {
|
||||||
|
node.getChildNodes().setInPara(true);
|
||||||
|
}
|
||||||
|
if (isInLink() || name.equals("a")) {
|
||||||
|
node.getChildNodes().setInLink(true);
|
||||||
|
}
|
||||||
|
add(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlNode addText(String content) {
|
||||||
|
if (content != null) {
|
||||||
|
XhtmlNode node = new XhtmlNode(NodeType.Text);
|
||||||
|
node.setContent(content);
|
||||||
|
add(node);
|
||||||
|
return node;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return list.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return list.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<XhtmlNode> iterator() {
|
||||||
|
return list.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
return list.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T[] toArray(T[] a) {
|
||||||
|
return list.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(XhtmlNode e) {
|
||||||
|
return list.add(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return list.remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(Collection<?> c) {
|
||||||
|
return list.containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(Collection<? extends XhtmlNode> c) {
|
||||||
|
return list.addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(int index, Collection<? extends XhtmlNode> c) {
|
||||||
|
return list.addAll(index, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
return list.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
return list.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XhtmlNode get(int index) {
|
||||||
|
return list.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XhtmlNode set(int index, XhtmlNode element) {
|
||||||
|
return list.set(index, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int index, XhtmlNode element) {
|
||||||
|
list.add(index, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XhtmlNode remove(int index) {
|
||||||
|
return list.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(Object o) {
|
||||||
|
return list.indexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int lastIndexOf(Object o) {
|
||||||
|
return list.lastIndexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListIterator<XhtmlNode> listIterator() {
|
||||||
|
return list.listIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListIterator<XhtmlNode> listIterator(int index) {
|
||||||
|
return list.listIterator(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<XhtmlNode> subList(int fromIndex, int toIndex) {
|
||||||
|
return list.subList(fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addChildren(XhtmlNodeList childNodes) {
|
||||||
|
this.addAll(childNodes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,8 +16,9 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.BindingResolution;
|
||||||
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ProfileKnowledgeProvider;
|
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.XmlParser;
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
|
Loading…
Reference in New Issue