more PE work
This commit is contained in:
parent
d532af808b
commit
44ecfbf53d
|
@ -228,6 +228,9 @@ public abstract class Base implements Serializable, IBase, IElement {
|
||||||
throw new FHIRException("Attempt to add child with unknown name "+name);
|
throw new FHIRException("Attempt to add child with unknown name "+name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean removeChild(String name, Base value) {
|
||||||
|
throw new FHIRException("Attempt to remove child with unknown name "+name);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Supports iterating the children elements in some generic processor or browser
|
* Supports iterating the children elements in some generic processor or browser
|
||||||
* All defined children will be listed, even if they have no value on this instance
|
* All defined children will be listed, even if they have no value on this instance
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.ResourceFactory;
|
import org.hl7.fhir.r5.model.ResourceFactory;
|
||||||
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.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ public class PEBuilder {
|
||||||
private ContextUtilities cu;
|
private ContextUtilities cu;
|
||||||
private PEElementPropertiesPolicy elementProps;
|
private PEElementPropertiesPolicy elementProps;
|
||||||
private boolean fixedPropsDefault;
|
private boolean fixedPropsDefault;
|
||||||
|
private FHIRPathEngine fpe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context - must be loaded with R5 definitions
|
* @param context - must be loaded with R5 definitions
|
||||||
|
@ -97,6 +99,28 @@ public class PEBuilder {
|
||||||
this.fixedPropsDefault = fixedPropsDefault;
|
this.fixedPropsDefault = fixedPropsDefault;
|
||||||
pu = new ProfileUtilities(context, null, null);
|
pu = new ProfileUtilities(context, null, null);
|
||||||
cu = new ContextUtilities(context);
|
cu = new ContextUtilities(context);
|
||||||
|
fpe = new FHIRPathEngine(context, pu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a profile, return a tree of the elements defined in the profile model. This builds the profile model
|
||||||
|
* for the provided version of the nominated profile
|
||||||
|
*
|
||||||
|
* The tree of elements in the profile model is different to those defined in the base resource:
|
||||||
|
* - some elements are removed (max = 0)
|
||||||
|
* - extensions are turned into named elements
|
||||||
|
* - slices are turned into named elements
|
||||||
|
* - element properties - doco, cardinality, binding etc is updated for what the profile says
|
||||||
|
*
|
||||||
|
* Warning: profiles and resources are recursive; you can't iterate this tree until it you get
|
||||||
|
* to the leaves because there are nodes that don't terminate (extensions have extensions)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public PEDefinition buildPEDefinition(StructureDefinition profile) {
|
||||||
|
if (!profile.hasSnapshot()) {
|
||||||
|
throw new DefinitionException("Profile '"+profile.getVersionedUrl()+"' does not have a snapshot");
|
||||||
|
}
|
||||||
|
return new PEDefinitionResource(this, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,6 +192,25 @@ public class PEBuilder {
|
||||||
return loadInstance(defn, resource);
|
return loadInstance(defn, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a resource and a profile, return a tree of instance data as defined by the profile model
|
||||||
|
* using the provided version of the profile
|
||||||
|
*
|
||||||
|
* The tree is a facade to the underlying resource - all actual data is stored against the resource,
|
||||||
|
* and retrieved on the fly from the resource, so that applications can work at either level, as
|
||||||
|
* convenient.
|
||||||
|
*
|
||||||
|
* Note that there's a risk that deleting something through the resource while holding
|
||||||
|
* a handle to a PEInstance that is a facade on what is deleted leaves an orphan facade
|
||||||
|
* that will continue to function, but is making changes to resource content that is no
|
||||||
|
* longer part of the resource
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public PEInstance buildPEInstance(StructureDefinition profile, Resource resource) {
|
||||||
|
PEDefinition defn = buildPEDefinition(profile);
|
||||||
|
return loadInstance(defn, resource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a resource and a profile, return a tree of instance data as defined by the profile model
|
* Given a resource and a profile, return a tree of instance data as defined by the profile model
|
||||||
* using the nominated version of the profile
|
* using the nominated version of the profile
|
||||||
|
@ -206,6 +249,25 @@ public class PEBuilder {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the provided version of a profile, construct a resource and fill out any fixed or required elements
|
||||||
|
*
|
||||||
|
* Note that fixed values are filled out irrespective of the value of fixedProps when the builder is created
|
||||||
|
*
|
||||||
|
* @param profile the profile
|
||||||
|
* @param meta whether to mark the profile in Resource.meta.profile
|
||||||
|
* @return constructed resource
|
||||||
|
*/
|
||||||
|
public Resource createResource(StructureDefinition profile, boolean meta) {
|
||||||
|
PEDefinition definition = buildPEDefinition(profile);
|
||||||
|
Resource res = ResourceFactory.createResource(definition.types().get(0).getType());
|
||||||
|
populateByProfile(res, definition);
|
||||||
|
if (meta) {
|
||||||
|
res.getMeta().addProfile(definition.profile.getUrl());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the current version of a profile, construct a resource and fill out any fixed or required elements
|
* For the current version of a profile, construct a resource and fill out any fixed or required elements
|
||||||
*
|
*
|
||||||
|
@ -414,7 +476,7 @@ public class PEBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PEInstance loadInstance(PEDefinition defn, Resource resource) {
|
private PEInstance loadInstance(PEDefinition defn, Resource resource) {
|
||||||
throw new NotImplementedException("Not done yet");
|
return new PEInstance(this, defn, resource, resource, defn.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWorkerContext getContext() {
|
public IWorkerContext getContext() {
|
||||||
|
@ -496,4 +558,8 @@ public class PEBuilder {
|
||||||
}
|
}
|
||||||
return getByName(elements, path);
|
return getByName(elements, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Base> exec(Resource resource, Base data, String fhirpath) {
|
||||||
|
return fpe.evaluate(this, resource, resource, data, fhirpath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,16 @@ public abstract class PEDefinition {
|
||||||
*/
|
*/
|
||||||
public abstract String fhirpath();
|
public abstract String fhirpath();
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isList() {
|
||||||
|
return "*".equals(definition.getBase().getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean repeats() {
|
||||||
|
return max() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class PEDefinitionExtension extends PEDefinition {
|
||||||
if (ved.isRequired() || eed.isProhibited()) {
|
if (ved.isRequired() || eed.isProhibited()) {
|
||||||
return "extension('"+extension.getUrl()+"').value";
|
return "extension('"+extension.getUrl()+"').value";
|
||||||
} else {
|
} else {
|
||||||
return "extension('"+extension.getUrl()+"').extension";
|
return "extension('"+extension.getUrl()+"')";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,46 @@
|
||||||
package org.hl7.fhir.r5.profilemodel;
|
package org.hl7.fhir.r5.profilemodel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
import org.hl7.fhir.r5.model.BaseDateTimeType;
|
||||||
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
|
import org.hl7.fhir.r5.model.ContactPoint;
|
||||||
|
import org.hl7.fhir.r5.model.Identifier;
|
||||||
import org.hl7.fhir.r5.model.DataType;
|
import org.hl7.fhir.r5.model.DataType;
|
||||||
|
import org.hl7.fhir.r5.model.DateTimeType;
|
||||||
|
import org.hl7.fhir.r5.model.HumanName;
|
||||||
|
import org.hl7.fhir.r5.model.Address;
|
||||||
|
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||||
|
import org.hl7.fhir.r5.model.Quantity;
|
||||||
|
import org.hl7.fhir.r5.model.Reference;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
|
||||||
public abstract class PEInstance {
|
/**
|
||||||
|
* This class provides a profile centric view of a resource, as driven by a profile
|
||||||
|
*
|
||||||
|
* This class is also suitable to be used as the base of a POJO
|
||||||
|
* @author grahamegrieve
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PEInstance {
|
||||||
|
|
||||||
|
private PEBuilder builder;
|
||||||
private PEDefinition definition;
|
private PEDefinition definition;
|
||||||
|
private Resource resource; // for FHIRPath
|
||||||
private Base data;
|
private Base data;
|
||||||
|
private String path;
|
||||||
|
|
||||||
protected PEInstance(PEDefinition definition, Base data) {
|
protected PEInstance(PEBuilder builder, PEDefinition definition, Resource resource, Base data, String path) {
|
||||||
super();
|
super();
|
||||||
|
this.builder = builder;
|
||||||
this.definition = definition;
|
this.definition = definition;
|
||||||
|
this.resource = resource;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,60 +62,178 @@ public abstract class PEInstance {
|
||||||
*/
|
*/
|
||||||
public List<PEInstance> children() {
|
public List<PEInstance> children() {
|
||||||
List<PEInstance> res = new ArrayList<>();
|
List<PEInstance> res = new ArrayList<>();
|
||||||
|
for (PEDefinition child : definition.children()) {
|
||||||
|
List<Base> instances = builder.exec(resource, data, child.fhirpath());
|
||||||
|
int i = 0;
|
||||||
|
for (Base b : instances) {
|
||||||
|
res.add(new PEInstance(builder, child, resource, b, path+"."+child.name()+(child.repeats() ? "["+i+"]": "")));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return all the single children of this instance data for the named property. An exception if there's more than one, null if there's none
|
||||||
|
*/
|
||||||
|
public PEInstance child(String name) {
|
||||||
|
PEDefinition child = byName(definition.children(), name);
|
||||||
|
List<Base> instances = builder.exec(resource, data, child.fhirpath());
|
||||||
|
if (instances.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
} else if (instances.size() == 1) {
|
||||||
|
return new PEInstance(builder, child, resource, instances.get(0), path+"."+child.name()+(child.repeats() ? "[0]": ""));
|
||||||
|
} else {
|
||||||
|
throw new FHIRException("Found multiple instances for "+name+"@ "+path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return all the children of this instance data for the named property
|
* @return all the children of this instance data for the named property
|
||||||
*/
|
*/
|
||||||
public List<PEInstance> children(String name) {
|
public List<PEInstance> children(String name) {
|
||||||
// PEDefinition child = definition.childByName(name);
|
PEDefinition child = byName(definition.children(), name);
|
||||||
// if (child = null) {
|
List<PEInstance> res = new ArrayList<>();
|
||||||
//
|
List<Base> instances = builder.exec(resource, data, child.fhirpath());
|
||||||
// }
|
int i = 0;
|
||||||
return null;
|
for (Base b : instances) {
|
||||||
|
res.add(new PEInstance(builder, child, resource, b, path+"."+child.name()+(child.repeats() ? "["+i+"]": "")));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private PEDefinition byName(List<PEDefinition> children, String name) {
|
||||||
* @return all the children of this instance data with the named property and the named type (for polymorphic
|
for (PEDefinition defn : children) {
|
||||||
*/
|
if (defn.name().equals(name)) {
|
||||||
public abstract List<PEInstance> children(String name, String type);
|
return defn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new FHIRException("No children with the name '"+name+"'");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return make a child, and append it to existing children (if they exist)
|
* @return make a child, and append it to existing children (if they exist)
|
||||||
*/
|
*/
|
||||||
public abstract PEInstance makeChild(String name);
|
public PEInstance makeChild(String name) {
|
||||||
|
PEDefinition child = byName(definition.children(), name);
|
||||||
|
Base b = data.addChild(child.schemaName());
|
||||||
|
builder.populateByProfile(b, child);
|
||||||
|
return new PEInstance(builder, child, resource, b, path+"."+child.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return get a child. if it doesn't exist, make one
|
||||||
|
*/
|
||||||
|
public PEInstance forceChild(String name) {
|
||||||
|
PEDefinition child = byName(definition.children(), name);
|
||||||
|
List<Base> instances = builder.exec(resource, data, child.fhirpath());
|
||||||
|
if (instances.isEmpty()) {
|
||||||
|
Base b = data.addChild(child.schemaName());
|
||||||
|
builder.populateByProfile(b, child);
|
||||||
|
return new PEInstance(builder, child, resource, b, path+"."+child.name()+(child.isList() ? "[0]": ""));
|
||||||
|
} else {
|
||||||
|
return new PEInstance(builder, child, resource, instances.get(0), path+"."+child.name()+(child.repeats() ? "[0]": ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove the nominated child from the resource
|
* remove the nominated child from the resource
|
||||||
*/
|
*/
|
||||||
public abstract void removeChild(PEInstance child);
|
public boolean removeChild(PEInstance child) {
|
||||||
|
return data.removeChild(child.definition().schemaName(), child.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum PEInstanceDataKind {
|
public enum PEInstanceDataKind {
|
||||||
Resource, Complex, DataType, PrimitiveValue
|
Resource, Complex, DataType, Primitive
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the kind of data behind this profiled node
|
* @return the kind of data behind this profiled node
|
||||||
*/
|
*/
|
||||||
public abstract PEInstanceDataKind getDataKind();
|
public PEInstanceDataKind getDataKind() {
|
||||||
|
if (data instanceof Resource) {
|
||||||
|
return PEInstanceDataKind.Resource;
|
||||||
|
}
|
||||||
|
if (data instanceof PrimitiveType) {
|
||||||
|
return PEInstanceDataKind.Primitive;
|
||||||
|
}
|
||||||
|
if (data instanceof DataType) {
|
||||||
|
return PEInstanceDataKind.DataType;
|
||||||
|
}
|
||||||
|
return PEInstanceDataKind.Complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Base data() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if dataKind = Resource, get the underlying resource, otherwise an exception
|
* @return if dataKind = Resource, get the underlying resource, otherwise an exception
|
||||||
*/
|
*/
|
||||||
public abstract Resource asResource();
|
public Resource asResource() {
|
||||||
|
return (Resource) data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if dataKind = Datatype, get the underlying resource, otherwise an exception
|
* @return if dataKind = Datatype, get the underlying resource, otherwise an exception
|
||||||
*/
|
*/
|
||||||
public abstract DataType asDataType();
|
public DataType asDataType() {
|
||||||
|
return (DataType) data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConcept asCodeableConcept() {
|
||||||
|
return (CodeableConcept) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier Identifier() {
|
||||||
|
return (Identifier) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Quantity asQuantity() {
|
||||||
|
return (Quantity) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HumanName asHumanName() {
|
||||||
|
return (HumanName) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address Address() {
|
||||||
|
return (Address) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactPoint asContactPoint() {
|
||||||
|
return (ContactPoint) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Reference asReference() {
|
||||||
|
return (Reference) asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if dataKind = PrimitiveValue, get the underlying resource, otherwise an exception
|
* @return if dataKind = PrimitiveValue, get the underlying resource, otherwise an exception
|
||||||
*
|
*
|
||||||
* Note that this is for e.g. String.value, not String itself
|
* Note that this is for e.g. String.value, not String itself
|
||||||
*/
|
*/
|
||||||
public abstract String getPrimitiveValue();
|
public String getPrimitiveAsString() {
|
||||||
|
return data.primitiveValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getPrimitiveAsDate() {
|
||||||
|
if (data instanceof BaseDateTimeType) {
|
||||||
|
return ((DateTimeType) data).getValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimitiveValue(String value) {
|
||||||
|
PrimitiveType<?> pt = (PrimitiveType<?>) data;
|
||||||
|
pt.setValueAsString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.hl7.fhir.r5.profilemodel.gen;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEInstance;
|
||||||
|
|
||||||
|
public class PEGeneratedBase {
|
||||||
|
|
||||||
|
protected PEInstance instance;
|
||||||
|
|
||||||
|
protected void removeChild(String string) {
|
||||||
|
PEInstance child = instance.child("simple");
|
||||||
|
if (child != null) {
|
||||||
|
instance.removeChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.hl7.fhir.r5.profilemodel.gen;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.model.CodeType;
|
||||||
|
import org.hl7.fhir.r5.model.Observation;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEBuilder;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a manually written example of the code that a POJO code
|
||||||
|
* generator for Profiles would produce
|
||||||
|
*
|
||||||
|
* @author grahamegrieve
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProfileExample extends PEGeneratedBase {
|
||||||
|
|
||||||
|
public ProfileExample(IWorkerContext context, Observation observation) {
|
||||||
|
super();
|
||||||
|
PEBuilder builder = new PEBuilder(context, PEElementPropertiesPolicy.EXTENSION_ID, true);
|
||||||
|
instance = builder.buildPEInstance("http://hl7.org/fhir/test/StructureDefinition/pe-profile1", "0.1", observation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple, type code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CodeType getSimple() {
|
||||||
|
return (CodeType) instance.forceChild("simple").asDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSimple() {
|
||||||
|
return instance.child("simple") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileExample clearSimple() {
|
||||||
|
removeChild("simple");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this doesn't exist, because of the way infrastructure works.
|
||||||
|
* You get the value and set the properties
|
||||||
|
*/
|
||||||
|
// public void setSimple() {
|
||||||
|
// return (CodeType) instance.forceChild("simple").asDataType();
|
||||||
|
// }
|
||||||
|
}
|
|
@ -6,12 +6,15 @@ import java.util.List;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
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;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
import org.hl7.fhir.r5.model.Observation;
|
import org.hl7.fhir.r5.model.Observation;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEDefinition;
|
import org.hl7.fhir.r5.profilemodel.PEDefinition;
|
||||||
|
import org.hl7.fhir.r5.profilemodel.PEInstance;
|
||||||
import org.hl7.fhir.r5.profilemodel.PEType;
|
import org.hl7.fhir.r5.profilemodel.PEType;
|
||||||
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.test.utils.TestPackageLoader;
|
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.npm.FilesystemPackageCacheManager;
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
|
@ -66,7 +69,7 @@ public class PETests {
|
||||||
checkElement(children.get(4), "contained", "contained", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Resource", 4, "contained");
|
checkElement(children.get(4), "contained", "contained", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Resource", 4, "contained");
|
||||||
checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple') or (url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')).not())");
|
checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple') or (url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')).not())");
|
||||||
checkElement(children.get(6), "extension", "simple", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple').value");
|
checkElement(children.get(6), "extension", "simple", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple').value");
|
||||||
checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex').extension");
|
checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')");
|
||||||
checkElement(children.get(8), "identifier", "identifier", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Identifier", 7, "identifier");
|
checkElement(children.get(8), "identifier", "identifier", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Identifier", 7, "identifier");
|
||||||
checkElement(children.get(9), "status", "status", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/code", 2, "status");
|
checkElement(children.get(9), "status", "status", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/code", 2, "status");
|
||||||
checkElement(children.get(10), "category", "category", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category");
|
checkElement(children.get(10), "category", "category", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category");
|
||||||
|
@ -287,7 +290,6 @@ public class PETests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate() throws IOException {
|
public void testCreate() throws IOException {
|
||||||
load();
|
load();
|
||||||
|
@ -301,4 +303,50 @@ public class PETests {
|
||||||
System.out.println(json);
|
System.out.println(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoad() throws IOException {
|
||||||
|
load();
|
||||||
|
|
||||||
|
Resource res = new JsonParser().parse(TestingUtilities.loadTestResource("R5", "pe-observation-1.json"));
|
||||||
|
PEInstance obs = new PEBuilder(ctxt, PEElementPropertiesPolicy.EXTENSION, true).buildPEInstance("http://hl7.org/fhir/test/StructureDefinition/pe-profile1", res);
|
||||||
|
|
||||||
|
PEInstance status = obs.child("status");
|
||||||
|
Assertions.assertNotNull(status);
|
||||||
|
Assertions.assertEquals("TestProfile.status", status.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.Primitive, status.getDataKind());
|
||||||
|
Assertions.assertEquals("final", status.asDataType().primitiveValue());
|
||||||
|
Assertions.assertEquals("final", status.getPrimitiveAsString());
|
||||||
|
|
||||||
|
PEInstance code = obs.child("code");
|
||||||
|
Assertions.assertNotNull(code);
|
||||||
|
Assertions.assertEquals("TestProfile.code", code.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.DataType, code.getDataKind());
|
||||||
|
Assertions.assertEquals("76690-7", code.asCodeableConcept().getCodingFirstRep().getCode());
|
||||||
|
|
||||||
|
PEInstance simple = obs.child("simple");
|
||||||
|
Assertions.assertNotNull(simple);
|
||||||
|
Assertions.assertEquals("TestProfile.simple", simple.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.Primitive, simple.getDataKind());
|
||||||
|
Assertions.assertEquals("14647-2", simple.getPrimitiveAsString());
|
||||||
|
|
||||||
|
PEInstance complex = obs.child("complex");
|
||||||
|
Assertions.assertNotNull(complex);
|
||||||
|
Assertions.assertEquals("TestProfile.complex", complex.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.DataType, complex.getDataKind());
|
||||||
|
|
||||||
|
PEInstance slice1 = complex.child("slice1");
|
||||||
|
Assertions.assertNotNull(slice1);
|
||||||
|
Assertions.assertEquals("TestProfile.complex.slice1[0]", slice1.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.DataType, slice1.getDataKind());
|
||||||
|
Assertions.assertEquals("18767-4", ((Coding) slice1.asDataType()).getCode());
|
||||||
|
|
||||||
|
PEInstance slice2 = complex.child("slice2");
|
||||||
|
Assertions.assertNotNull(slice2);
|
||||||
|
Assertions.assertEquals("TestProfile.complex.slice2[0]", slice2.getPath());
|
||||||
|
Assertions.assertEquals(PEInstanceDataKind.Primitive, slice2.getDataKind());
|
||||||
|
Assertions.assertEquals("A string value", slice2.getPrimitiveAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue