round trip constraint xpath after R5 changes
This commit is contained in:
parent
2f0a45046e
commit
fd77fd16d0
|
@ -381,14 +381,14 @@ public class ElementDefinition10_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHumanElement()) tgt.setHumanElement(String10_50.convertString(src.getHumanElement()));
|
||||
tgt.setExpression(ToolingExtensions.readStringExtension(src, ToolingExtensions.EXT_EXPRESSION));
|
||||
// if (src.hasXpathElement()) tgt.setXpathElement(String10_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpathElement()) tgt.setXpathElement(String10_50.convertString(src.getXpathElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
public static org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
|
||||
if (src == null || src.isEmpty()) return null;
|
||||
org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent();
|
||||
ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyElement(src, tgt);
|
||||
ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyElement(src, tgt, org.hl7.fhir.r5.utils.ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
if (src.hasKeyElement()) tgt.setKeyElement(Id10_50.convertId(src.getKeyElement()));
|
||||
if (src.hasRequirementsElement())
|
||||
tgt.setRequirementsElement(String10_50.convertString(src.getRequirementsElement()));
|
||||
|
@ -396,7 +396,7 @@ public class ElementDefinition10_50 {
|
|||
if (src.hasHumanElement()) tgt.setHumanElement(String10_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression())
|
||||
ToolingExtensions.addStringExtension(tgt, ToolingExtensions.EXT_EXPRESSION, src.getExpression());
|
||||
// if (src.hasXpathElement()) tgt.setXpathElement(String10_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpathElement()) tgt.setXpathElement(String10_50.convertString(src.getXpathElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
|
|
|
@ -496,20 +496,20 @@ public class ElementDefinition14_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpression(convertToR4Expression(src.getExpression()));
|
||||
// if (src.hasXpathElement()) tgt.setXpathElement(String14_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpathElement()) tgt.setXpathElement(String14_50.convertString(src.getXpathElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
public static ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
|
||||
if (src == null || src.isEmpty()) return null;
|
||||
ElementDefinition.ElementDefinitionConstraintComponent tgt = new ElementDefinition.ElementDefinitionConstraintComponent();
|
||||
ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyElement(src, tgt);
|
||||
ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyElement(src, tgt, org.hl7.fhir.r5.utils.ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
if (src.hasKeyElement()) tgt.setKeyElement(Id14_50.convertId(src.getKeyElement()));
|
||||
if (src.hasRequirements()) tgt.setRequirementsElement(String14_50.convertString(src.getRequirementsElement()));
|
||||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpression(convertTo2016MayExpression(src.getExpression()));
|
||||
// if (src.hasXpathElement()) tgt.setXpathElement(String14_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpathElement()) tgt.setXpathElement(String14_50.convertString(src.getXpathElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ public class ElementDefinition30_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String30_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String30_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String30_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSource(src.getSource());
|
||||
return tgt;
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ public class ElementDefinition30_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String30_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String30_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String30_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSource(src.getSource());
|
||||
return tgt;
|
||||
}
|
||||
|
|
|
@ -519,7 +519,7 @@ public class ElementDefinition40_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String40_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String40_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String40_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSourceElement(Canonical40_50.convertCanonical(src.getSourceElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
@ -527,13 +527,13 @@ public class ElementDefinition40_50 {
|
|||
public static org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
|
||||
if (src == null) return null;
|
||||
org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent();
|
||||
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt);
|
||||
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt, org.hl7.fhir.r5.utils.ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
if (src.hasKey()) tgt.setKeyElement(Id40_50.convertId(src.getKeyElement()));
|
||||
if (src.hasRequirements()) tgt.setRequirementsElement(String40_50.convertString(src.getRequirementsElement()));
|
||||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String40_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String40_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String40_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSourceElement(Canonical40_50.convertCanonical(src.getSourceElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
|
|
@ -519,7 +519,7 @@ public class ElementDefinition43_50 {
|
|||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String43_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String43_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String43_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSourceElement(Canonical43_50.convertCanonical(src.getSourceElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
@ -527,13 +527,13 @@ public class ElementDefinition43_50 {
|
|||
public static org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
|
||||
if (src == null) return null;
|
||||
org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent();
|
||||
ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt);
|
||||
ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt, org.hl7.fhir.r5.utils.ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
if (src.hasKey()) tgt.setKeyElement(Id43_50.convertId(src.getKeyElement()));
|
||||
if (src.hasRequirements()) tgt.setRequirementsElement(String43_50.convertString(src.getRequirementsElement()));
|
||||
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
|
||||
if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement()));
|
||||
if (src.hasExpression()) tgt.setExpressionElement(String43_50.convertString(src.getExpressionElement()));
|
||||
// if (src.hasXpath()) tgt.setXpathElement(String43_50.convertString(src.getXpathElement()));
|
||||
if (src.hasXpath()) tgt.setXpathElement(String43_50.convertString(src.getXpathElement()));
|
||||
if (src.hasSource()) tgt.setSourceElement(Canonical43_50.convertCanonical(src.getSourceElement()));
|
||||
return tgt;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package org.hl7.fhir.convertors.conv40_50;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class StructureDefinition40_50Test {
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("Test r5 -> r4 AuditEvent conversion.")
|
||||
public void testR5_R4() throws IOException {
|
||||
byte[] r4_input = TestingUtilities.loadTestResourceBytes("conversion", "sd-xpath-constraint-r4.xml");
|
||||
byte[] r5_input = TestingUtilities.loadTestResourceBytes("conversion", "sd-xpath-constraint-r5.xml");
|
||||
|
||||
org.hl7.fhir.r5.model.StructureDefinition r5_actual = (org.hl7.fhir.r5.model.StructureDefinition) new org.hl7.fhir.r5.formats.XmlParser().parse(r5_input);
|
||||
org.hl7.fhir.r4.model.StructureDefinition r4_conv = (org.hl7.fhir.r4.model.StructureDefinition) VersionConvertorFactory_40_50.convertResource(r5_actual);
|
||||
byte[] r4_output = new org.hl7.fhir.r4.formats.XmlParser().setOutputStyle(org.hl7.fhir.r4.formats.IParser.OutputStyle.PRETTY).composeBytes(r4_conv);
|
||||
|
||||
if (!r4_input.equals(r4_output)) {
|
||||
TextFile.bytesToFile(r4_output, Utilities.path("[tmp]", "r4-sd-out.xml"));
|
||||
TextFile.bytesToFile(r4_input, Utilities.path("[tmp]", "r4-sd-in.xml"));
|
||||
}
|
||||
assertArrayEquals(r4_input, r4_output);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("Test r4 -> r5 AuditEvent conversion.")
|
||||
public void testR4_R5() throws IOException {
|
||||
byte[] r4_input = TestingUtilities.loadTestResourceBytes("conversion", "sd-xpath-constraint-r4.xml");
|
||||
byte[] r5_input = TestingUtilities.loadTestResourceBytes("conversion", "sd-xpath-constraint-r5.xml");
|
||||
|
||||
org.hl7.fhir.r4.model.StructureDefinition r4_actual = (org.hl7.fhir.r4.model.StructureDefinition) new org.hl7.fhir.r4.formats.XmlParser().parse(r4_input);
|
||||
org.hl7.fhir.r5.model.StructureDefinition r5_conv = (org.hl7.fhir.r5.model.StructureDefinition) VersionConvertorFactory_40_50.convertResource(r4_actual);
|
||||
byte[] r5_output = new org.hl7.fhir.r5.formats.XmlParser().setOutputStyle(org.hl7.fhir.r5.formats.IParser.OutputStyle.PRETTY).composeBytes(r5_conv);
|
||||
|
||||
|
||||
if (!r5_input.equals(r5_output)) {
|
||||
TextFile.bytesToFile(r5_output, Utilities.path("[tmp]", "r5-sd-out.xml"));
|
||||
TextFile.bytesToFile(r5_input, Utilities.path("[tmp]", "r5-sd-in.xml"));
|
||||
}
|
||||
assertArrayEquals(r5_input, r5_output);
|
||||
}
|
||||
|
||||
}
|
|
@ -4497,12 +4497,30 @@ public boolean hasTarget() {
|
|||
, suppress, human, expression, source);
|
||||
}
|
||||
|
||||
public String fhirType() {
|
||||
return "ElementDefinition.constraint";
|
||||
public String fhirType() {
|
||||
return "ElementDefinition.constraint";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public boolean hasXpathElement() {
|
||||
return hasExtension(ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
}
|
||||
|
||||
public boolean hasXpath() {
|
||||
return hasExtension(ToolingExtensions.EXT_XPATH_CONSTRAINT);
|
||||
}
|
||||
|
||||
public StringType getXpathElement() {
|
||||
return hasXpathElement() ? getExtensionByUrl(ToolingExtensions.EXT_XPATH_CONSTRAINT).getValueStringType() : new StringType();
|
||||
}
|
||||
|
||||
public void setXpathElement(StringType value) {
|
||||
if (hasXpath()) {
|
||||
getExtensionByUrl(ToolingExtensions.EXT_XPATH_CONSTRAINT).setValue(value);
|
||||
} else {
|
||||
addExtension(ToolingExtensions.EXT_XPATH_CONSTRAINT, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Block()
|
||||
public static class ElementDefinitionObligationComponent extends Element implements IBaseDatatypeElement {
|
||||
|
|
|
@ -1,74 +1,148 @@
|
|||
package org.hl7.fhir.r5.profilemodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
|
||||
public class ProfiledElement {
|
||||
|
||||
ProfiledElementBuilder builder;
|
||||
String name;
|
||||
StructureDefinition baseStructure;
|
||||
ElementDefinition baseDefinition;
|
||||
StructureDefinition profileStructure;
|
||||
ElementDefinition profiledDefinition;
|
||||
Base data; // might be null if we're not attached to an instance
|
||||
private List<ProfiledElement> children;
|
||||
private Object sliceDefinition;
|
||||
|
||||
/**
|
||||
* Don't create one of these directly - always use the public methods on ProfiledElementBuilder
|
||||
*
|
||||
* @param builder
|
||||
* @param baseElement
|
||||
* @param profiledElement
|
||||
* @param data
|
||||
*/
|
||||
protected ProfiledElement(ProfiledElementBuilder builder, String name, ElementDefinition baseDefinition,
|
||||
ElementDefinition profiledDefinition, Base data) {
|
||||
super();
|
||||
this.builder = builder;
|
||||
this.name = name;
|
||||
this.baseDefinition = baseDefinition;
|
||||
this.profiledDefinition = profiledDefinition;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
protected ProfiledElement(ProfiledElementBuilder builder, String name, StructureDefinition base, ElementDefinition baseDefinition,
|
||||
StructureDefinition profile, ElementDefinition profiledDefinition) {
|
||||
this.builder = builder;
|
||||
this.name = name;
|
||||
this.baseStructure = base;
|
||||
this.baseDefinition = baseDefinition;
|
||||
this.profileStructure = profile;
|
||||
this.profiledDefinition = profiledDefinition;
|
||||
}
|
||||
|
||||
public ProfiledElement(ProfiledElementBuilder builder, String name, StructureDefinition base, ElementDefinition baseDefinition,
|
||||
StructureDefinition profile, ElementDefinition profiledDefinition, ElementDefinition sliceDefinition) {
|
||||
this.builder = builder;
|
||||
this.name = name;
|
||||
this.baseStructure = base;
|
||||
this.baseDefinition = baseDefinition;
|
||||
this.profileStructure = profile;
|
||||
this.profiledDefinition = profiledDefinition;
|
||||
this.sliceDefinition = sliceDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the element or slice in the profile (always unique amongst children)
|
||||
*/
|
||||
public String name() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the element in the resource (may be different to the slice name)
|
||||
*/
|
||||
public String schemaName() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return baseDefinition.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of types. There is always at least one type; it might be Element, Type, BackboneElement or BackboneType
|
||||
*/
|
||||
public List<String> types() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
List<String> res = new ArrayList<>();
|
||||
if (!profiledDefinition.hasType()) {
|
||||
if (!profiledDefinition.getPath().contains(".")) {
|
||||
res.add(profileStructure.getType());
|
||||
} else {
|
||||
throw new DefinitionException("What?");
|
||||
}
|
||||
} else {
|
||||
for (TypeRefComponent t : profiledDefinition.getType()) {
|
||||
if (t.hasProfile()) {
|
||||
for (CanonicalType u : t.getProfile()) {
|
||||
res.add(t.getWorkingCode()+"["+u.getValue()+"]");
|
||||
}
|
||||
} else {
|
||||
res.add(t.getWorkingCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The minimum number of repeats allowed
|
||||
*/
|
||||
public int min() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return profiledDefinition.getMin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum number of repeats allowed
|
||||
*/
|
||||
public int max() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return "*".equals(profiledDefinition.getMax()) ? Integer.MAX_VALUE : Integer.parseInt(profiledDefinition.getMax());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the definition of the element in the profile (fully populated)
|
||||
*/
|
||||
public ElementDefinition definition() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return profiledDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the definition of the element in the base specification
|
||||
*/
|
||||
public ElementDefinition baseDefinition() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return baseDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the short documentation of the definition (shown in the profile table view)
|
||||
*/
|
||||
public String shortDocumentation() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return profiledDefinition.getShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full definition of the element (markdown syntax)
|
||||
*/
|
||||
public String documentation() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
return profiledDefinition.getDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,11 +158,37 @@ public class ProfiledElement {
|
|||
*
|
||||
* Note that the children returned from this instance can run off the
|
||||
* end of the data provided, and then inDataMode() is false
|
||||
*
|
||||
* Warning: profiles and resources can be recursive; you can't iterate this tree until it you get
|
||||
* to the leaves because you will never get to a child that doesn't have children
|
||||
*
|
||||
*/
|
||||
public List<ProfiledElement> children(String type) {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
if (children == null) {
|
||||
if (!profiledDefinition.hasType() && profileStructure.getType().equals(type)) {
|
||||
children = builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, null);
|
||||
} else {
|
||||
for (TypeRefComponent t : profiledDefinition.getType()) {
|
||||
if (t.hasProfile()) {
|
||||
for (CanonicalType u : t.getProfile()) {
|
||||
if ((t.getWorkingCode()+"["+u.getValue()+"]").equals(type)) {
|
||||
children = builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, t, u);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (t.getWorkingCode().equals(type)) {
|
||||
children = builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (children != null) {
|
||||
return children;
|
||||
}
|
||||
throw new DefinitionException("Unable to understand type '"+type+"'");
|
||||
}
|
||||
|
||||
|
||||
// -- instance data ---------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -152,7 +252,11 @@ public class ProfiledElement {
|
|||
public String setPrimitiveValue() {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name+"("+schemaName()+"):"+types().toString()+" ["+min()+":"+max()+"] \""+shortDocumentation()+"\"";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
package org.hl7.fhir.r5.profilemodel;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.NotImplementedError;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.ResourceFactory;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
||||
public class ProfiledElementBuilder {
|
||||
|
||||
private IWorkerContext context;
|
||||
private ProfileUtilities pu;
|
||||
|
||||
public ProfiledElementBuilder(IWorkerContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
pu = new ProfileUtilities(context, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +44,15 @@ public class ProfiledElementBuilder {
|
|||
*
|
||||
*/
|
||||
public ProfiledElement buildProfileElement(String url) {
|
||||
throw new NotImplementedError("NOt done yet");
|
||||
StructureDefinition profile = getProfile(url);
|
||||
if (profile == null) {
|
||||
throw new DefinitionException("Unable to find profile for URL '"+url+"'");
|
||||
}
|
||||
StructureDefinition base = context.fetchTypeDefinition(profile.getType());
|
||||
if (base == null) {
|
||||
throw new DefinitionException("Unable to find base type '"+profile.getType()+"' for URL '"+url+"'");
|
||||
}
|
||||
return new ProfiledElement(this, profile.getName(), base, base.getSnapshot().getElementFirstRep(), profile, profile.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,7 +72,15 @@ public class ProfiledElementBuilder {
|
|||
*
|
||||
*/
|
||||
public ProfiledElement buildProfileElement(String url, String version) {
|
||||
throw new NotImplementedError("NOt done yet");
|
||||
StructureDefinition profile = getProfile(url, version);
|
||||
if (profile == null) {
|
||||
throw new DefinitionException("Unable to find profile for URL '"+url+"'");
|
||||
}
|
||||
StructureDefinition base = context.fetchTypeDefinition(profile.getType());
|
||||
if (base == null) {
|
||||
throw new DefinitionException("Unable to find base type '"+profile.getType()+"' for URL '"+url+"'");
|
||||
}
|
||||
return new ProfiledElement(this, profile.getName(), base, base.getSnapshot().getElementFirstRep(), profile, profile.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +101,7 @@ public class ProfiledElementBuilder {
|
|||
*
|
||||
*/
|
||||
public ProfiledElement buildProfileElement(String url, Resource resource) {
|
||||
throw new NotImplementedError("NOt done yet");
|
||||
throw new NotImplementedException("NOt done yet");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +119,7 @@ public class ProfiledElementBuilder {
|
|||
*
|
||||
*/
|
||||
public ProfiledElement buildProfileElement(String url, String version, Resource resource) {
|
||||
throw new NotImplementedError("NOt done yet");
|
||||
throw new NotImplementedException("NOt done yet");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,7 +129,67 @@ public class ProfiledElementBuilder {
|
|||
* No version, because the version doesn't change the type of the resource
|
||||
*/
|
||||
public Resource makeProfileBase(String url) {
|
||||
throw new NotImplementedError("NOt done yet");
|
||||
StructureDefinition profile = getProfile(url);
|
||||
return ResourceFactory.createResource(profile.getType());
|
||||
}
|
||||
|
||||
|
||||
// -- methods below here are only used internally to the package
|
||||
|
||||
private StructureDefinition getProfile(String url) {
|
||||
return context.fetchResource(StructureDefinition.class, url);
|
||||
}
|
||||
|
||||
|
||||
private StructureDefinition getProfile(String url, String version) {
|
||||
return context.fetchResource(StructureDefinition.class, url, version);
|
||||
}
|
||||
|
||||
protected List<ProfiledElement> listChildren(StructureDefinition baseStructure, ElementDefinition baseDefinition,
|
||||
StructureDefinition profileStructure, ElementDefinition profiledDefinition, TypeRefComponent t, CanonicalType u) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected List<ProfiledElement> listChildren(StructureDefinition baseStructure, ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition, TypeRefComponent t) {
|
||||
if (profileDefinition.getType().size() == 1 || (!profileDefinition.getPath().contains("."))) {
|
||||
assert profileDefinition.getType().size() != 1 || profileDefinition.getType().contains(t);
|
||||
List<ElementDefinition> list = pu.getChildList(profileStructure, profileDefinition);
|
||||
if (list != null && list.size() > 0) {
|
||||
List<ElementDefinition> blist = pu.getChildList(baseStructure, baseDefinition);
|
||||
List<ProfiledElement> res = new ArrayList<>();
|
||||
int i = 0;
|
||||
while (i < list.size()) {
|
||||
ElementDefinition defn = list.get(i);
|
||||
if (defn.hasSlicing()) {
|
||||
i++;
|
||||
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
|
||||
res.add(new ProfiledElement(this, list.get(i).getSliceName(), baseStructure, getByName(blist, defn), profileStructure, list.get(i), defn));
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
res.add(new ProfiledElement(this, defn.getName(), baseStructure, getByName(blist, defn), profileStructure, defn));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
throw new DefinitionException("not done yet");
|
||||
}
|
||||
} else {
|
||||
throw new DefinitionException("not done yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ElementDefinition getByName(List<ElementDefinition> blist, ElementDefinition defn) {
|
||||
for (ElementDefinition ed : blist) {
|
||||
if (ed.getPath().equals(defn.getPath())) {
|
||||
return ed;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
generateCopyright(x, cs );
|
||||
}
|
||||
|
||||
generateProperties(x, cs);
|
||||
boolean props = generateProperties(x, cs);
|
||||
generateFilters(x, cs);
|
||||
List<UsedConceptMap> maps = new ArrayList<UsedConceptMap>();
|
||||
hasExtensions = generateCodeSystemContent(x, cs, hasExtensions, maps);
|
||||
hasExtensions = generateCodeSystemContent(x, cs, hasExtensions, maps, props);
|
||||
|
||||
return hasExtensions;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
private void generateProperties(XhtmlNode x, CodeSystem cs) {
|
||||
private boolean generateProperties(XhtmlNode x, CodeSystem cs) {
|
||||
if (cs.hasProperty()) {
|
||||
boolean hasRendered = false;
|
||||
boolean hasURI = false;
|
||||
|
@ -104,6 +104,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Properties", getContext().getLang()));
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "This code system defines the following properties for its concepts", getContext().getLang()));
|
||||
XhtmlNode tbl = x.table("grid");
|
||||
XhtmlNode tr = tbl.tr();
|
||||
if (hasRendered) {
|
||||
|
@ -131,10 +132,16 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
tr.td().tx(p.getDescription());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List<UsedConceptMap> maps, boolean props) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (props) {
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Concepts", getContext().getLang()));
|
||||
}
|
||||
XhtmlNode p = x.para();
|
||||
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system "));
|
||||
p.code().tx(cs.getUrl());
|
||||
|
|
|
@ -241,6 +241,7 @@ public class ToolingExtensions {
|
|||
|
||||
public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions";
|
||||
public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment";
|
||||
public static final String EXT_XPATH_CONSTRAINT = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.constraint.xpath";
|
||||
;
|
||||
|
||||
// specific extension helpers
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package org.hl7.fhir.r5.profiles;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.profilemodel.ProfiledElement;
|
||||
import org.hl7.fhir.r5.profilemodel.ProfiledElementBuilder;
|
||||
import org.hl7.fhir.r5.test.utils.TestPackageLoader;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ProfiledElementTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatientCore() throws IOException {
|
||||
IWorkerContext ctxt = TestingUtilities.getSharedWorkerContext();
|
||||
FilesystemPackageCacheManager pc = new FilesystemPackageCacheManager(true);
|
||||
NpmPackage npm = pc.loadPackage("hl7.fhir.us.core", "5.0.0");
|
||||
ctxt.loadFromPackage(npm, new TestPackageLoader(new String[] { "StructureDefinition" }));
|
||||
|
||||
ProfiledElement pe = new ProfiledElementBuilder(ctxt).buildProfileElement("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient");
|
||||
|
||||
Assertions.assertEquals("USCorePatientProfile", pe.name());
|
||||
Assertions.assertEquals("Patient", pe.schemaName());
|
||||
Assertions.assertEquals(0, pe.min());
|
||||
Assertions.assertEquals(Integer.MAX_VALUE, pe.max());
|
||||
Assertions.assertEquals("Patient", pe.types().get(0));
|
||||
Assertions.assertNotNull(pe.definition());
|
||||
Assertions.assertNotNull(pe.baseDefinition());
|
||||
Assertions.assertEquals("Information about an individual or animal receiving health care services", pe.shortDocumentation());
|
||||
Assertions.assertEquals("\\-", pe.documentation());
|
||||
|
||||
List<ProfiledElement> children = pe.children("Patient");
|
||||
Assertions.assertEquals(27, children.size());
|
||||
|
||||
pe = children.get(8);
|
||||
Assertions.assertEquals("us-core-birthsex", pe.name());
|
||||
Assertions.assertEquals("extension", pe.schemaName());
|
||||
Assertions.assertEquals(0, pe.min());
|
||||
Assertions.assertEquals(1, pe.max());
|
||||
Assertions.assertEquals("code", pe.types().get(0));
|
||||
Assertions.assertNotNull(pe.definition());
|
||||
Assertions.assertNotNull(pe.baseDefinition());
|
||||
Assertions.assertEquals("Information about an individual or animal receiving health care services", pe.shortDocumentation());
|
||||
Assertions.assertEquals("\\-", pe.documentation());
|
||||
|
||||
pe = children.get(7);
|
||||
|
||||
Assertions.assertEquals("ethnicity", pe.name());
|
||||
Assertions.assertEquals("extension", pe.schemaName());
|
||||
Assertions.assertEquals(0, pe.min());
|
||||
Assertions.assertEquals(1, pe.max());
|
||||
Assertions.assertEquals("extension", pe.types().get(0));
|
||||
Assertions.assertNotNull(pe.definition());
|
||||
Assertions.assertNotNull(pe.baseDefinition());
|
||||
Assertions.assertEquals("Information about an individual or animal receiving health care services", pe.shortDocumentation());
|
||||
Assertions.assertEquals("\\-", pe.documentation());
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue