round trip constraint xpath after R5 changes

This commit is contained in:
Grahame Grieve 2022-12-23 15:14:25 +13:00
parent 2f0a45046e
commit fd77fd16d0
12 changed files with 385 additions and 43 deletions

View File

@ -381,14 +381,14 @@ public class ElementDefinition10_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHumanElement()) tgt.setHumanElement(String10_50.convertString(src.getHumanElement())); if (src.hasHumanElement()) tgt.setHumanElement(String10_50.convertString(src.getHumanElement()));
tgt.setExpression(ToolingExtensions.readStringExtension(src, ToolingExtensions.EXT_EXPRESSION)); 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; return tgt;
} }
public static org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException { public static org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
if (src == null || src.isEmpty()) return null; if (src == null || src.isEmpty()) return null;
org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent(); 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.hasKeyElement()) tgt.setKeyElement(Id10_50.convertId(src.getKeyElement()));
if (src.hasRequirementsElement()) if (src.hasRequirementsElement())
tgt.setRequirementsElement(String10_50.convertString(src.getRequirementsElement())); 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.hasHumanElement()) tgt.setHumanElement(String10_50.convertString(src.getHumanElement()));
if (src.hasExpression()) if (src.hasExpression())
ToolingExtensions.addStringExtension(tgt, ToolingExtensions.EXT_EXPRESSION, src.getExpression()); 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; return tgt;
} }

View File

@ -496,20 +496,20 @@ public class ElementDefinition14_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement())); if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpression(convertToR4Expression(src.getExpression())); 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; return tgt;
} }
public static ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException { public static ElementDefinition.ElementDefinitionConstraintComponent convertElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent src) throws FHIRException {
if (src == null || src.isEmpty()) return null; if (src == null || src.isEmpty()) return null;
ElementDefinition.ElementDefinitionConstraintComponent tgt = new ElementDefinition.ElementDefinitionConstraintComponent(); 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.hasKeyElement()) tgt.setKeyElement(Id14_50.convertId(src.getKeyElement()));
if (src.hasRequirements()) tgt.setRequirementsElement(String14_50.convertString(src.getRequirementsElement())); if (src.hasRequirements()) tgt.setRequirementsElement(String14_50.convertString(src.getRequirementsElement()));
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement())); if (src.hasHumanElement()) tgt.setHumanElement(String14_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpression(convertTo2016MayExpression(src.getExpression())); 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; return tgt;
} }

View File

@ -558,7 +558,7 @@ public class ElementDefinition30_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String30_50.convertString(src.getExpressionElement())); 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()); if (src.hasSource()) tgt.setSource(src.getSource());
return tgt; return tgt;
} }
@ -572,7 +572,7 @@ public class ElementDefinition30_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String30_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String30_50.convertString(src.getExpressionElement())); 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()); if (src.hasSource()) tgt.setSource(src.getSource());
return tgt; return tgt;
} }

View File

@ -519,7 +519,7 @@ public class ElementDefinition40_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String40_50.convertString(src.getExpressionElement())); 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())); if (src.hasSource()) tgt.setSourceElement(Canonical40_50.convertCanonical(src.getSourceElement()));
return tgt; 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 { 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; if (src == null) return null;
org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent(); 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.hasKey()) tgt.setKeyElement(Id40_50.convertId(src.getKeyElement()));
if (src.hasRequirements()) tgt.setRequirementsElement(String40_50.convertString(src.getRequirementsElement())); if (src.hasRequirements()) tgt.setRequirementsElement(String40_50.convertString(src.getRequirementsElement()));
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String40_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String40_50.convertString(src.getExpressionElement())); 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())); if (src.hasSource()) tgt.setSourceElement(Canonical40_50.convertCanonical(src.getSourceElement()));
return tgt; return tgt;
} }

View File

@ -519,7 +519,7 @@ public class ElementDefinition43_50 {
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String43_50.convertString(src.getExpressionElement())); 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())); if (src.hasSource()) tgt.setSourceElement(Canonical43_50.convertCanonical(src.getSourceElement()));
return tgt; 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 { 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; if (src == null) return null;
org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent tgt = new org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent(); 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.hasKey()) tgt.setKeyElement(Id43_50.convertId(src.getKeyElement()));
if (src.hasRequirements()) tgt.setRequirementsElement(String43_50.convertString(src.getRequirementsElement())); if (src.hasRequirements()) tgt.setRequirementsElement(String43_50.convertString(src.getRequirementsElement()));
if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement())); if (src.hasSeverity()) tgt.setSeverityElement(convertConstraintSeverity(src.getSeverityElement()));
if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement())); if (src.hasHuman()) tgt.setHumanElement(String43_50.convertString(src.getHumanElement()));
if (src.hasExpression()) tgt.setExpressionElement(String43_50.convertString(src.getExpressionElement())); 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())); if (src.hasSource()) tgt.setSourceElement(Canonical43_50.convertCanonical(src.getSourceElement()));
return tgt; return tgt;
} }

View File

@ -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);
}
}

View File

@ -4497,12 +4497,30 @@ public boolean hasTarget() {
, suppress, human, expression, source); , suppress, human, expression, source);
} }
public String fhirType() { public String fhirType() {
return "ElementDefinition.constraint"; 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() @Block()
public static class ElementDefinitionObligationComponent extends Element implements IBaseDatatypeElement { public static class ElementDefinitionObligationComponent extends Element implements IBaseDatatypeElement {

View File

@ -1,74 +1,148 @@
package org.hl7.fhir.r5.profilemodel; package org.hl7.fhir.r5.profilemodel;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.NotImplementedException; 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;
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; import org.hl7.fhir.r5.model.ValueSet;
public class ProfiledElement { 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) * @return The name of the element or slice in the profile (always unique amongst children)
*/ */
public String name() { 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) * @return The name of the element in the resource (may be different to the slice name)
*/ */
public String schemaName() { 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 * @return a list of types. There is always at least one type; it might be Element, Type, BackboneElement or BackboneType
*/ */
public List<String> types() { 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 * @return The minimum number of repeats allowed
*/ */
public int min() { public int min() {
throw new NotImplementedException("Not done yet"); return profiledDefinition.getMin();
} }
/** /**
* @return the maximum number of repeats allowed * @return the maximum number of repeats allowed
*/ */
public int max() { 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) * @return the definition of the element in the profile (fully populated)
*/ */
public ElementDefinition definition() { public ElementDefinition definition() {
throw new NotImplementedException("Not done yet"); return profiledDefinition;
} }
/** /**
* @return the definition of the element in the base specification * @return the definition of the element in the base specification
*/ */
public ElementDefinition baseDefinition() { public ElementDefinition baseDefinition() {
throw new NotImplementedException("Not done yet"); return baseDefinition;
} }
/** /**
* @return the short documentation of the definition (shown in the profile table view) * @return the short documentation of the definition (shown in the profile table view)
*/ */
public String shortDocumentation() { public String shortDocumentation() {
throw new NotImplementedException("Not done yet"); return profiledDefinition.getShort();
} }
/** /**
* @return the full definition of the element (markdown syntax) * @return the full definition of the element (markdown syntax)
*/ */
public String documentation() { 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 * Note that the children returned from this instance can run off the
* end of the data provided, and then inDataMode() is false * 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) { 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 --------------------------------------- // -- instance data ---------------------------------------
/** /**
@ -152,7 +252,11 @@ public class ProfiledElement {
public String setPrimitiveValue() { public String setPrimitiveValue() {
throw new NotImplementedException("Not done yet"); throw new NotImplementedException("Not done yet");
} }
@Override
public String toString() {
return name+"("+schemaName()+"):"+types().toString()+" ["+min()+":"+max()+"] \""+shortDocumentation()+"\"";
}
} }

View File

@ -1,17 +1,29 @@
package org.hl7.fhir.r5.profilemodel; package org.hl7.fhir.r5.profilemodel;
import org.hl7.fhir.r5.context.IWorkerContext; import java.util.ArrayList;
import org.hl7.fhir.r5.model.Resource; 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 { public class ProfiledElementBuilder {
private IWorkerContext context; private IWorkerContext context;
private ProfileUtilities pu;
public ProfiledElementBuilder(IWorkerContext context) { public ProfiledElementBuilder(IWorkerContext context) {
super(); super();
this.context = context; this.context = context;
pu = new ProfileUtilities(context, null, null);
} }
@ -32,7 +44,15 @@ public class ProfiledElementBuilder {
* *
*/ */
public ProfiledElement buildProfileElement(String url) { 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) { 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) { 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) { 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 * No version, because the version doesn't change the type of the resource
*/ */
public Resource makeProfileBase(String url) { 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;
} }
} }

View File

@ -55,10 +55,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
generateCopyright(x, cs ); generateCopyright(x, cs );
} }
generateProperties(x, cs); boolean props = generateProperties(x, cs);
generateFilters(x, cs); generateFilters(x, cs);
List<UsedConceptMap> maps = new ArrayList<UsedConceptMap>(); List<UsedConceptMap> maps = new ArrayList<UsedConceptMap>();
hasExtensions = generateCodeSystemContent(x, cs, hasExtensions, maps); hasExtensions = generateCodeSystemContent(x, cs, hasExtensions, maps, props);
return hasExtensions; 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()) { if (cs.hasProperty()) {
boolean hasRendered = false; boolean hasRendered = false;
boolean hasURI = 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", "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 tbl = x.table("grid");
XhtmlNode tr = tbl.tr(); XhtmlNode tr = tbl.tr();
if (hasRendered) { if (hasRendered) {
@ -131,10 +132,16 @@ public class CodeSystemRenderer extends TerminologyRenderer {
tr.td().tx(p.getDescription()); 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(); XhtmlNode p = x.para();
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system ")); p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system "));
p.code().tx(cs.getUrl()); p.code().tx(cs.getUrl());

View File

@ -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 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_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 // specific extension helpers

View File

@ -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());
}
}