more work on PE definitions
This commit is contained in:
parent
50bc157ab9
commit
d532af808b
|
@ -1497,6 +1497,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.setMaxLength(usage.getMaxLength());
|
||||
if (!res.hasMustSupport() && usage.hasMustSupport())
|
||||
res.setMustSupport(usage.getMustSupport());
|
||||
if (!res.hasMustHaveValue() && usage.hasMustHaveValue())
|
||||
res.setMustHaveValue(usage.getMustHaveValue());
|
||||
if (!res.hasBinding() && usage.hasBinding())
|
||||
res.setBinding(usage.getBinding().copy());
|
||||
for (ElementDefinitionConstraintComponent c : usage.getConstraint())
|
||||
|
@ -2217,6 +2219,18 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
else
|
||||
derived.getMustSupportElement().setUserData(DERIVATION_EQUALS, true);
|
||||
}
|
||||
|
||||
if (derived.hasMustHaveValueElement()) {
|
||||
if (!(base.hasMustHaveValueElement() && Base.compareDeep(derived.getMustHaveValueElement(), base.getMustHaveValueElement(), false))) {
|
||||
if (base.hasMustHaveValue() && base.getMustHaveValue() && !derived.getMustHaveValue()) {
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Illegal constraint [must-have-value = false] when [must-have-value = true] in the base profile", ValidationMessage.IssueSeverity.ERROR));
|
||||
}
|
||||
base.setMustHaveValueElement(derived.getMustHaveValueElement().copy());
|
||||
} else if (trimDifferential)
|
||||
derived.setMustHaveValueElement(null);
|
||||
else
|
||||
derived.getMustHaveValueElement().setUserData(DERIVATION_EQUALS, true);
|
||||
}
|
||||
|
||||
|
||||
// profiles cannot change : isModifier, defaultValue, meaningWhenMissing
|
||||
|
|
|
@ -2392,8 +2392,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
|
||||
|
||||
@Override
|
||||
public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps) {
|
||||
public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps, boolean fixedProps) {
|
||||
// TODO Auto-generated method stub
|
||||
return new PEBuilder(this, elementProps);
|
||||
return new PEBuilder(this, elementProps, fixedProps);
|
||||
}
|
||||
}
|
|
@ -804,6 +804,6 @@ public interface IWorkerContext {
|
|||
|
||||
public String getSpecUrl();
|
||||
|
||||
public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps);
|
||||
public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps, boolean fixedProps);
|
||||
|
||||
}
|
|
@ -6,18 +6,21 @@ import java.util.List;
|
|||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
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.DiscriminatorType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules;
|
||||
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;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
/**
|
||||
|
@ -73,24 +76,27 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
*/
|
||||
public class PEBuilder {
|
||||
|
||||
|
||||
public enum PEElementPropertiesPolicy {
|
||||
NONE, EXTENSION, EXTENSION_ID
|
||||
}
|
||||
|
||||
private IWorkerContext context;
|
||||
private ProfileUtilities pu;
|
||||
private ContextUtilities cu;
|
||||
private PEElementPropertiesPolicy elementProps;
|
||||
private boolean fixedPropsDefault;
|
||||
|
||||
/**
|
||||
* @param context - must be loaded with R5 definitions
|
||||
* @param elementProps - whether to include Element.id and Element.extension in the tree. Recommended choice: Extension
|
||||
*/
|
||||
public PEBuilder(IWorkerContext context, PEElementPropertiesPolicy elementProps) {
|
||||
public PEBuilder(IWorkerContext context, PEElementPropertiesPolicy elementProps, boolean fixedPropsDefault) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.elementProps = elementProps;
|
||||
this.fixedPropsDefault = fixedPropsDefault;
|
||||
pu = new ProfileUtilities(context, null, null);
|
||||
cu = new ContextUtilities(context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,11 +121,7 @@ public class PEBuilder {
|
|||
if (!profile.hasSnapshot()) {
|
||||
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
||||
}
|
||||
StructureDefinition base = context.fetchTypeDefinition(profile.getType());
|
||||
if (base == null) {
|
||||
throw new DefinitionException("Unable to find base type '"+profile.getType()+"' for URL '"+url+"'");
|
||||
}
|
||||
return new PEDefinitionResource(this, base, profile);
|
||||
return new PEDefinitionResource(this, profile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,11 +146,7 @@ public class PEBuilder {
|
|||
if (!profile.hasSnapshot()) {
|
||||
throw new DefinitionException("Profile '"+url+"' does not have a snapshot");
|
||||
}
|
||||
StructureDefinition base = context.fetchTypeDefinition(profile.getType());
|
||||
if (base == null) {
|
||||
throw new DefinitionException("Unable to find base type '"+profile.getType()+"' for URL '"+url+"'");
|
||||
}
|
||||
return new PEDefinitionResource(this, base, profile);
|
||||
return new PEDefinitionResource(this, profile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,16 +187,45 @@ public class PEBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a profile, construct an empty resource of the type being profiled (to use as input
|
||||
* to the buildPEInstance method
|
||||
* For the current version of a profile, construct a resource and fill out any fixed or required elements
|
||||
*
|
||||
* No version, because the version doesn't change the type of the resource
|
||||
* Note that fixed values are filled out irrespective of the value of fixedProps when the builder is created
|
||||
*
|
||||
* @param url identifies the profile
|
||||
* @param version identifies the version of the profile
|
||||
* @param meta whether to mark the profile in Resource.meta.profile
|
||||
* @return constructed resource
|
||||
*/
|
||||
public Resource makeProfileBase(String url) {
|
||||
StructureDefinition profile = getProfile(url);
|
||||
return ResourceFactory.createResource(profile.getType());
|
||||
public Resource createResource(String url, String version, boolean meta) {
|
||||
PEDefinition definition = buildPEDefinition(url, version);
|
||||
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
|
||||
*
|
||||
* Note that fixed values are filled out irrespective of the value of fixedProps when the builder is created
|
||||
*
|
||||
* @param url identifies the profile
|
||||
* @param meta whether to mark the profile in Resource.meta.profile
|
||||
* @return constructed resource
|
||||
*/
|
||||
public Resource createResource(String url, boolean meta) {
|
||||
PEDefinition definition = buildPEDefinition(url);
|
||||
Resource res = ResourceFactory.createResource(definition.types().get(0).getType());
|
||||
populateByProfile(res, definition);
|
||||
if (meta) {
|
||||
res.getMeta().addProfile(definition.profile.getUrl());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- methods below here are only used internally to the package
|
||||
|
||||
|
@ -210,41 +237,34 @@ public class PEBuilder {
|
|||
private StructureDefinition getProfile(String url, String version) {
|
||||
return context.fetchResource(StructureDefinition.class, url, version);
|
||||
}
|
||||
//
|
||||
// protected List<PEDefinition> listChildren(boolean allFixed, StructureDefinition profileStructure, ElementDefinition definition, TypeRefComponent t, CanonicalType u) {
|
||||
// // TODO Auto-generated method stub
|
||||
// return null;
|
||||
// }
|
||||
|
||||
protected List<PEDefinition> listChildren(StructureDefinition baseStructure, ElementDefinition baseDefinition,
|
||||
StructureDefinition profileStructure, ElementDefinition profiledDefinition, TypeRefComponent t, CanonicalType u) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<PEDefinition> listChildren(StructureDefinition baseStructure, ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition, String url, String... omitList) {
|
||||
protected List<PEDefinition> listChildren(boolean allFixed, PEDefinition parent, StructureDefinition profileStructure, ElementDefinition definition, String url, String... omitList) {
|
||||
StructureDefinition profile = profileStructure;
|
||||
List<ElementDefinition> list = pu.getChildList(profile, profileDefinition);
|
||||
if (profileDefinition.getType().size() == 1 || (!profileDefinition.getPath().contains(".")) || list.isEmpty()) {
|
||||
assert url == null || checkType(profileDefinition, url);
|
||||
List<ElementDefinition> list = pu.getChildList(profile, definition);
|
||||
if (definition.getType().size() == 1 || (!definition.getPath().contains(".")) || list.isEmpty()) {
|
||||
assert url == null || checkType(definition, url);
|
||||
List<PEDefinition> res = new ArrayList<>();
|
||||
if (list.size() == 0) {
|
||||
profile = context.fetchResource(StructureDefinition.class, url);
|
||||
list = pu.getChildList(profile, profile.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
StructureDefinition base = baseStructure;
|
||||
List<ElementDefinition> blist = pu.getChildList(baseStructure, baseDefinition);
|
||||
if (blist.size() == 0) {
|
||||
base = context.fetchTypeDefinition(url);
|
||||
blist = pu.getChildList(base, base.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
int i = 0;
|
||||
while (i < list.size()) {
|
||||
ElementDefinition defn = list.get(i);
|
||||
if (include(defn)) {
|
||||
ElementDefinition bdefn = getByName(blist, defn);
|
||||
if (bdefn == null) {
|
||||
throw new Error("no base definition for "+defn.getId());
|
||||
}
|
||||
if (passElementPropsCheck(bdefn) && !Utilities.existsInList(bdefn.getName(), omitList)) {
|
||||
PEDefinitionElement pe = new PEDefinitionElement(this, base, bdefn, profileStructure, defn);
|
||||
pe.setRecursing(profileDefinition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
|
||||
if (!defn.getMax().equals("0") && (allFixed || include(defn))) {
|
||||
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
|
||||
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn);
|
||||
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
|
||||
if (cu.isPrimitiveDatatype(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
|
||||
pe.setMustHaveValue(definition.getMustHaveValue());
|
||||
}
|
||||
pe.setInFixedValue(definition.hasFixed() || definition.hasPattern() || parent.isInFixedValue());
|
||||
if (defn.hasSlicing()) {
|
||||
if (defn.getSlicing().getRules() != SlicingRules.CLOSED) {
|
||||
res.add(pe);
|
||||
|
@ -253,11 +273,11 @@ public class PEBuilder {
|
|||
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
|
||||
StructureDefinition ext = getExtensionDefinition(list.get(i));
|
||||
if (ext != null) {
|
||||
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), baseStructure, getByName(blist, defn), profileStructure, list.get(i), defn, ext));
|
||||
res.add(new PEDefinitionExtension(this, list.get(i).getSliceName(), profile, list.get(i), defn, ext));
|
||||
} else if (isTypeSlicing(defn)) {
|
||||
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), baseStructure, getByName(blist, defn), profileStructure, list.get(i), defn));
|
||||
res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn));
|
||||
} else {
|
||||
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), baseStructure, getByName(blist, defn), profileStructure, list.get(i), defn));
|
||||
res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -301,24 +321,22 @@ public class PEBuilder {
|
|||
}
|
||||
|
||||
private boolean include(ElementDefinition defn) {
|
||||
if (defn.getMax().equals("0")) {
|
||||
return false;
|
||||
if (fixedPropsDefault) {
|
||||
return true;
|
||||
} else {
|
||||
return !(defn.hasFixed() || defn.hasPattern());
|
||||
}
|
||||
if (defn.hasFixed() || defn.hasPattern()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected List<PEDefinition> listSlices(StructureDefinition baseStructure, ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition) {
|
||||
List<ElementDefinition> list = pu.getSliceList(profileStructure, profileDefinition);
|
||||
protected List<PEDefinition> listSlices(StructureDefinition profileStructure, ElementDefinition definition) {
|
||||
List<ElementDefinition> list = pu.getSliceList(profileStructure, definition);
|
||||
List<PEDefinition> res = new ArrayList<>();
|
||||
for (ElementDefinition ed : list) {
|
||||
if (profileStructure.getDerivation() == TypeDerivationRule.CONSTRAINT && profileStructure.getType().equals("Extension")) {
|
||||
res.add(new PEDefinitionSubExtension(this, baseStructure, baseDefinition, profileStructure, ed));
|
||||
res.add(new PEDefinitionSubExtension(this, profileStructure, ed));
|
||||
} else {
|
||||
PEDefinitionElement pe = new PEDefinitionElement(this, baseStructure, baseDefinition, profileStructure, ed);
|
||||
pe.setRecursing(profileDefinition == ed || (profileStructure.getDerivation() == TypeDerivationRule.SPECIALIZATION && profileStructure.getType().equals("Extension")));
|
||||
PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, ed);
|
||||
pe.setRecursing(definition == ed || (profileStructure.getDerivation() == TypeDerivationRule.SPECIALIZATION && profileStructure.getType().equals("Extension")));
|
||||
res.add(pe);
|
||||
}
|
||||
}
|
||||
|
@ -350,9 +368,9 @@ public class PEBuilder {
|
|||
}
|
||||
|
||||
|
||||
private ElementDefinition getByName(List<ElementDefinition> blist, ElementDefinition defn) {
|
||||
private ElementDefinition getByName(List<ElementDefinition> blist, String name) {
|
||||
for (ElementDefinition ed : blist) {
|
||||
if (ed.getName().equals(defn.getName())) {
|
||||
if (name.equals(ed.getName())) {
|
||||
return ed;
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +378,7 @@ public class PEBuilder {
|
|||
}
|
||||
|
||||
|
||||
public PEType makeType(TypeRefComponent t) {
|
||||
protected PEType makeType(TypeRefComponent t) {
|
||||
if (t.hasProfile()) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, t.getProfile().get(0).getValue());
|
||||
if (sd == null) {
|
||||
|
@ -373,7 +391,7 @@ public class PEBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
public PEType makeType(TypeRefComponent t, CanonicalType u) {
|
||||
protected PEType makeType(TypeRefComponent t, CanonicalType u) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
||||
if (sd == null) {
|
||||
return new PEType(tail(u.getValue()), t.getWorkingCode(), u.getValue());
|
||||
|
@ -383,7 +401,7 @@ public class PEBuilder {
|
|||
}
|
||||
|
||||
|
||||
public PEType makeType(String tn) {
|
||||
protected PEType makeType(String tn) {
|
||||
return new PEType(tn, tn, "http://hl7.org/fhir/StructureDefinition/"+ tn);
|
||||
}
|
||||
|
||||
|
@ -391,14 +409,91 @@ public class PEBuilder {
|
|||
return value.contains("/") ? value.substring(value.lastIndexOf("/")+1) : value;
|
||||
}
|
||||
|
||||
|
||||
public List<ElementDefinition> getChildren(StructureDefinition profileStructure, ElementDefinition profiledDefinition) {
|
||||
return pu.getChildList(profileStructure, profiledDefinition);
|
||||
protected List<ElementDefinition> getChildren(StructureDefinition profileStructure, ElementDefinition definition) {
|
||||
return pu.getChildList(profileStructure, definition);
|
||||
}
|
||||
|
||||
private PEInstance loadInstance(PEDefinition defn, Resource resource) {
|
||||
throw new NotImplementedException("Not done yet");
|
||||
}
|
||||
|
||||
public IWorkerContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
protected void populateByProfile(Base base, PEDefinition definition) {
|
||||
for (PEDefinition pe : definition.children(true)) {
|
||||
if (pe.fixedValue()) {
|
||||
if (pe.definition().hasPattern()) {
|
||||
base.setProperty(pe.schemaName(), pe.definition().getPattern());
|
||||
} else {
|
||||
base.setProperty(pe.schemaName(), pe.definition().getFixed());
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < pe.min(); i++) {
|
||||
Base b = null;
|
||||
if (pe.schemaName().endsWith("[x]")) {
|
||||
if (pe.types().size() == 1) {
|
||||
b = base.addChild(pe.schemaName().replace("[x]", Utilities.capitalize(pe.types().get(0).getType())));
|
||||
}
|
||||
} else {
|
||||
b = base.addChild(pe.schemaName());
|
||||
}
|
||||
if (b != null) {
|
||||
populateByProfile(b, pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String makeSliceExpression(StructureDefinition profile, ElementDefinitionSlicingComponent slicing, ElementDefinition definition) {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" and ");
|
||||
for (ElementDefinitionSlicingDiscriminatorComponent d : slicing.getDiscriminator()) {
|
||||
switch (d.getType()) {
|
||||
case EXISTS:
|
||||
throw new DefinitionException("The discriminator type 'exists' is not supported by the PEBuilder");
|
||||
case PATTERN:
|
||||
throw new DefinitionException("The discriminator type 'pattern' is not supported by the PEBuilder");
|
||||
case POSITION:
|
||||
throw new DefinitionException("The discriminator type 'position' is not supported by the PEBuilder");
|
||||
case PROFILE:
|
||||
throw new DefinitionException("The discriminator type 'profile' is not supported by the PEBuilder");
|
||||
case TYPE:
|
||||
throw new DefinitionException("The discriminator type 'type' is not supported by the PEBuilder");
|
||||
case VALUE:
|
||||
String path = d.getPath();
|
||||
if (path.contains(".")) {
|
||||
throw new DefinitionException("The discriminator path '"+path+"' is not supported by the PEBuilder");
|
||||
}
|
||||
ElementDefinition ed = getChildElement(profile, definition, path);
|
||||
if (ed == null) {
|
||||
throw new DefinitionException("The discriminator path '"+path+"' could not be resolved by the PEBuilder");
|
||||
}
|
||||
if (!ed.hasFixed()) {
|
||||
throw new DefinitionException("The discriminator path '"+path+"' has no fixed value - this is not supported by the PEBuilder");
|
||||
}
|
||||
if (!ed.getFixed().isPrimitive()) {
|
||||
throw new DefinitionException("The discriminator path '"+path+"' has a fixed value that is not a primitive ("+ed.getFixed().fhirType()+") - this is not supported by the PEBuilder");
|
||||
}
|
||||
b.append(path+" = '"+ed.getFixed().primitiveValue()+"'");
|
||||
break;
|
||||
case NULL:
|
||||
throw new DefinitionException("The discriminator type 'null' is not supported by the PEBuilder");
|
||||
default:
|
||||
throw new DefinitionException("The discriminator type '??' is not supported by the PEBuilder");
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private ElementDefinition getChildElement(StructureDefinition profile, ElementDefinition definition, String path) {
|
||||
List<ElementDefinition> elements = pu.getChildList(profile, definition);
|
||||
if (elements.size() == 0) {
|
||||
profile = definition.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, definition.getTypeFirstRep().getProfile().get(0).asStringValue()) :
|
||||
context.fetchTypeDefinition(definition.getTypeFirstRep().getWorkingCode());
|
||||
elements = pu.getChildList(profile, profile.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
return getByName(elements, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.xmlbeans.impl.xb.xsdschema.All;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -13,40 +15,36 @@ public abstract class PEDefinition {
|
|||
|
||||
protected PEBuilder builder;
|
||||
protected String name;
|
||||
protected StructureDefinition baseStructure;
|
||||
protected ElementDefinition baseDefinition;
|
||||
protected StructureDefinition profileStructure;
|
||||
protected ElementDefinition profiledDefinition;
|
||||
protected StructureDefinition profile;
|
||||
protected ElementDefinition definition;
|
||||
protected List<PEType> types;
|
||||
protected Map<String, List<PEDefinition>> children = new HashMap<>();
|
||||
private boolean recursing;
|
||||
private boolean mustHaveValue;
|
||||
private boolean inFixedValue;
|
||||
|
||||
/**
|
||||
* Don't create one of these directly - always use the public methods on ProfiledElementBuilder
|
||||
*
|
||||
* @param builder
|
||||
* @param baseElement
|
||||
* @param profiledElement
|
||||
* @param data
|
||||
*/
|
||||
protected PEDefinition(PEBuilder 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;
|
||||
}
|
||||
// /**
|
||||
// * Don't create one of these directly - always use the public methods on ProfiledElementBuilder
|
||||
// *
|
||||
// * @param builder
|
||||
// * @param baseElement
|
||||
// * @param profiledElement
|
||||
// * @param data
|
||||
// */
|
||||
// protected PEDefinition(PEBuilder builder, String name,
|
||||
// ElementDefinition definition, Base data) {
|
||||
// super();
|
||||
// this.builder = builder;
|
||||
// this.name = name;
|
||||
// this.definition = definition;
|
||||
//// this.data = data;
|
||||
// }
|
||||
|
||||
protected PEDefinition(PEBuilder builder, String name, StructureDefinition base, ElementDefinition baseDefinition,
|
||||
StructureDefinition profile, ElementDefinition profiledDefinition) {
|
||||
protected PEDefinition(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition) {
|
||||
this.builder = builder;
|
||||
this.name = name;
|
||||
this.baseStructure = base;
|
||||
this.baseDefinition = baseDefinition;
|
||||
this.profileStructure = profile;
|
||||
this.profiledDefinition = profiledDefinition;
|
||||
this.profile = profile;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +59,7 @@ public abstract class PEDefinition {
|
|||
* @return The name of the element in the resource (may be different to the slice name)
|
||||
*/
|
||||
public String schemaName() {
|
||||
return baseDefinition.getName();
|
||||
return definition.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,14 +82,14 @@ public abstract class PEDefinition {
|
|||
* @return The minimum number of repeats allowed
|
||||
*/
|
||||
public int min() {
|
||||
return profiledDefinition.getMin();
|
||||
return mustHaveValue ? 1 : definition.getMin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum number of repeats allowed
|
||||
*/
|
||||
public int max() {
|
||||
return profiledDefinition.getMax() == null || "*".equals(profiledDefinition.getMax()) ? Integer.MAX_VALUE : Integer.parseInt(profiledDefinition.getMax());
|
||||
return definition.getMax() == null || "*".equals(definition.getMax()) ? Integer.MAX_VALUE : Integer.parseInt(definition.getMax());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,7 +98,7 @@ public abstract class PEDefinition {
|
|||
* Note that the profile definition might be the same as a base definition, when the tree runs off the end of what's profiled
|
||||
*/
|
||||
public ElementDefinition definition() {
|
||||
return profiledDefinition;
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,21 +107,26 @@ public abstract class PEDefinition {
|
|||
* Note that the profile definition might be the same as a base definition, when the tree runs off the end of what's profiled
|
||||
*/
|
||||
public ElementDefinition baseDefinition() {
|
||||
return baseDefinition;
|
||||
String type = definition.getBase().getPath();
|
||||
if (type.contains(".")) {
|
||||
type= type.substring(0, type.indexOf("."));
|
||||
}
|
||||
StructureDefinition sd = builder.getContext().fetchTypeDefinition(type);
|
||||
return sd.getSnapshot().getElementByPath(definition.getBase().getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the short documentation of the definition (shown in the profile table view)
|
||||
*/
|
||||
public String shortDocumentation() {
|
||||
return profiledDefinition.getShort();
|
||||
return definition.getShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full definition of the element (markdown syntax)
|
||||
*/
|
||||
public String documentation() {
|
||||
return profiledDefinition.getDefinition();
|
||||
return definition.getDefinition();
|
||||
}
|
||||
|
||||
// /**
|
||||
|
@ -142,16 +145,43 @@ public abstract class PEDefinition {
|
|||
*
|
||||
*/
|
||||
public List<PEDefinition> children(String typeUrl) {
|
||||
if (children.containsKey(typeUrl)) {
|
||||
return children.get(typeUrl);
|
||||
}
|
||||
List<PEDefinition> res = new ArrayList<>();
|
||||
makeChildren(typeUrl, res);
|
||||
children.put(typeUrl, res);
|
||||
return res;
|
||||
return children(typeUrl, false);
|
||||
}
|
||||
|
||||
protected abstract void makeChildren(String typeUrl, List<PEDefinition> children);
|
||||
public List<PEDefinition> children(String typeUrl, boolean allFixed) {
|
||||
if (children.containsKey(typeUrl+"$"+allFixed)) {
|
||||
return children.get(typeUrl+"$"+allFixed);
|
||||
}
|
||||
List<PEDefinition> res = new ArrayList<>();
|
||||
makeChildren(typeUrl, res, allFixed);
|
||||
children.put(typeUrl+"$"+allFixed, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<PEDefinition> children() {
|
||||
if (types().size() == 1) {
|
||||
return children(types.get(0).getUrl(), false);
|
||||
} else {
|
||||
throw new DefinitionException("Attempt to get children for an element that doesn't have a single type (types = "+types()+")");
|
||||
}
|
||||
}
|
||||
|
||||
public List<PEDefinition> children(boolean allFixed) {
|
||||
if (types().size() == 1) {
|
||||
return children(types.get(0).getUrl(), allFixed);
|
||||
} else {
|
||||
throw new DefinitionException("Attempt to get children for an element that doesn't have a single type (types = "+types()+")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the element has a fixed value. This will always be false if fixedProps = false when the builder is created
|
||||
*/
|
||||
public boolean fixedValue() {
|
||||
return definition.hasFixed() || definition.hasPattern();
|
||||
}
|
||||
|
||||
protected abstract void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -171,8 +201,30 @@ public abstract class PEDefinition {
|
|||
this.recursing = recursing;
|
||||
}
|
||||
|
||||
protected boolean isMustHaveValue() {
|
||||
return mustHaveValue;
|
||||
}
|
||||
|
||||
protected void setMustHaveValue(boolean mustHaveValue) {
|
||||
this.mustHaveValue = mustHaveValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this property is inside an element that has an assigned fixed value
|
||||
*/
|
||||
public boolean isInFixedValue() {
|
||||
return inFixedValue;
|
||||
}
|
||||
|
||||
|
||||
protected void setInFixedValue(boolean inFixedValue) {
|
||||
this.inFixedValue = inFixedValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This is public to support unit testing - there's no reason to use it otherwise
|
||||
*
|
||||
* @return used in the instance processor to differentiate slices
|
||||
*/
|
||||
public abstract String fhirpath();
|
||||
|
|
|
@ -6,18 +6,17 @@ 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.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
||||
public class PEDefinitionElement extends PEDefinition {
|
||||
|
||||
public PEDefinitionElement(PEBuilder builder,
|
||||
StructureDefinition baseStructure, ElementDefinition baseDefinition,
|
||||
StructureDefinition profileStructure, ElementDefinition profileDefinition) {
|
||||
super(builder, baseDefinition.getName(), baseStructure, baseDefinition, profileStructure, profileDefinition);
|
||||
public PEDefinitionElement(PEBuilder builder, StructureDefinition profile, ElementDefinition definition) {
|
||||
super(builder, definition.getName(), profile, definition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listTypes(List<PEType> types) {
|
||||
for (TypeRefComponent t : profiledDefinition.getType()) {
|
||||
for (TypeRefComponent t : definition.getType()) {
|
||||
if (t.hasProfile()) {
|
||||
for (CanonicalType u : t.getProfile()) {
|
||||
types.add(builder.makeType(t, u));
|
||||
|
@ -29,13 +28,28 @@ public class PEDefinitionElement extends PEDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
children.addAll(builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, typeUrl));
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, definition, typeUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirpath() {
|
||||
return baseDefinition.getName();
|
||||
String base = definition.getName().replace("[x]", "");
|
||||
if (definition.hasSlicing()) {
|
||||
// get all the slices
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
|
||||
List<PEDefinition> slices = builder.listSlices(profile, definition);
|
||||
// list all the fhirpaths
|
||||
for (PEDefinition slice : slices) {
|
||||
b.append("("+builder.makeSliceExpression(profile, definition.getSlicing(), slice.definition())+")");
|
||||
}
|
||||
if (b.count() == 0)
|
||||
return base;
|
||||
else
|
||||
return base+".where(("+b.toString()+").not())";
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,11 +15,8 @@ public class PEDefinitionExtension extends PEDefinition {
|
|||
private ElementDefinition eed;
|
||||
private ElementDefinition ved;
|
||||
|
||||
public PEDefinitionExtension(PEBuilder builder, String name,
|
||||
StructureDefinition baseStructure, ElementDefinition baseDefinition,
|
||||
StructureDefinition profileStructure, ElementDefinition profileDefinition,
|
||||
ElementDefinition sliceDefinition, StructureDefinition extension) {
|
||||
super(builder, name, baseStructure, baseDefinition, profileStructure, profileDefinition);
|
||||
public PEDefinitionExtension(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition, StructureDefinition extension) {
|
||||
super(builder, name, profile, definition);
|
||||
this.sliceDefinition = sliceDefinition;
|
||||
this.extension= extension;
|
||||
eed = extension.getSnapshot().getElementByPath("Extension.extension");
|
||||
|
@ -44,14 +41,14 @@ public class PEDefinitionExtension extends PEDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
if (ved.isRequired() || eed.isProhibited()) {
|
||||
children.addAll(builder.listChildren(extension, ved, extension, ved, typeUrl));
|
||||
children.addAll(builder.listChildren(allFixed, this, extension, ved, typeUrl));
|
||||
} else {
|
||||
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
||||
children.addAll(builder.listChildren(extension, eed, extension, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||
children.addAll(builder.listChildren(allFixed, this, extension, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||
}
|
||||
children.addAll(builder.listSlices(extension, eed, extension, eed));
|
||||
children.addAll(builder.listSlices(extension, eed));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,23 +6,23 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
|
||||
public class PEDefinitionResource extends PEDefinition {
|
||||
|
||||
public PEDefinitionResource(PEBuilder builder, StructureDefinition base, StructureDefinition profile) {
|
||||
super(builder, profile.getName(), base, base.getSnapshot().getElementFirstRep(), profile, profile.getSnapshot().getElementFirstRep());
|
||||
public PEDefinitionResource(PEBuilder builder, StructureDefinition profile) {
|
||||
super(builder, profile.getName(), profile, profile.getSnapshot().getElementFirstRep());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listTypes(List<PEType> types) {
|
||||
types.add(new PEType(profileStructure.getName(), profileStructure.getType(), profileStructure.getUrl()));
|
||||
types.add(new PEType(profile.getName(), profile.getType(), profile.getUrl()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
children.addAll(builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, null));
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, definition, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirpath() {
|
||||
return profileStructure.getType();
|
||||
return profile.getType();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,16 +11,14 @@ public class PEDefinitionSlice extends PEDefinition {
|
|||
|
||||
protected ElementDefinition sliceDefinition;
|
||||
|
||||
public PEDefinitionSlice(PEBuilder builder, String name, StructureDefinition baseStructure,
|
||||
ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition,
|
||||
ElementDefinition sliceDefinition) {
|
||||
super(builder, name, baseStructure, baseDefinition, profileStructure, profileDefinition);
|
||||
public PEDefinitionSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition profileDefinition, ElementDefinition sliceDefinition) {
|
||||
super(builder, name, profile, profileDefinition);
|
||||
this.sliceDefinition = sliceDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listTypes(List<PEType> types) {
|
||||
for (TypeRefComponent t : profiledDefinition.getType()) {
|
||||
for (TypeRefComponent t : definition.getType()) {
|
||||
if (t.hasProfile()) {
|
||||
for (CanonicalType u : t.getProfile()) {
|
||||
types.add(builder.makeType(t, u));
|
||||
|
@ -32,13 +30,15 @@ public class PEDefinitionSlice extends PEDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
throw new Error("Not done yet");
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, definition, typeUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirpath() {
|
||||
throw new Error("Not done yet");
|
||||
String base = schemaName().replace("[x]", "");
|
||||
String filter = builder.makeSliceExpression(profile, sliceDefinition.getSlicing(), definition);
|
||||
return base+".where("+filter+")";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ public class PEDefinitionSubExtension extends PEDefinition {
|
|||
private ElementDefinition ved;
|
||||
private ElementDefinition ued;
|
||||
|
||||
public PEDefinitionSubExtension(PEBuilder builder, StructureDefinition baseStructure, ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition) {
|
||||
super(builder, profileDefinition.getSliceName(), baseStructure, baseDefinition, profileStructure, profileDefinition);
|
||||
List<ElementDefinition> childDefs = builder.getChildren(profileStructure, profiledDefinition);
|
||||
public PEDefinitionSubExtension(PEBuilder builder, StructureDefinition profile, ElementDefinition definition) {
|
||||
super(builder, definition.getSliceName(), profile, definition);
|
||||
List<ElementDefinition> childDefs = builder.getChildren(profile, definition);
|
||||
eed = getElementByName(childDefs, "extension");
|
||||
ved = getElementByName(childDefs, "value[x]");
|
||||
ued = getElementByName(childDefs, "url");
|
||||
|
@ -49,14 +49,14 @@ public class PEDefinitionSubExtension extends PEDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
if (ved.isRequired() || eed.isProhibited()) {
|
||||
children.addAll(builder.listChildren(baseStructure, baseDefinition, profileStructure, ved, typeUrl));
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, ved, typeUrl));
|
||||
} else {
|
||||
if (eed.getSlicing().getRules() != SlicingRules.CLOSED) {
|
||||
children.addAll(builder.listChildren(baseStructure, baseDefinition, profileStructure, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url"));
|
||||
}
|
||||
children.addAll(builder.listSlices(baseStructure, baseDefinition, profileStructure, eed));
|
||||
children.addAll(builder.listSlices(profile, eed));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,21 +6,20 @@ import org.hl7.fhir.r5.model.CanonicalType;
|
|||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
||||
public class PEDefinitionTypeSlice extends PEDefinition {
|
||||
|
||||
protected ElementDefinition sliceDefinition;
|
||||
|
||||
public PEDefinitionTypeSlice(PEBuilder builder, String name, StructureDefinition baseStructure,
|
||||
ElementDefinition baseDefinition, StructureDefinition profileStructure, ElementDefinition profileDefinition,
|
||||
ElementDefinition sliceDefinition) {
|
||||
super(builder, name, baseStructure, baseDefinition, profileStructure, profileDefinition);
|
||||
public PEDefinitionTypeSlice(PEBuilder builder, String name, StructureDefinition profile, ElementDefinition definition, ElementDefinition sliceDefinition) {
|
||||
super(builder, name, profile, definition);
|
||||
this.sliceDefinition = sliceDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listTypes(List<PEType> types) {
|
||||
for (TypeRefComponent t : profiledDefinition.getType()) {
|
||||
for (TypeRefComponent t : definition.getType()) {
|
||||
if (t.hasProfile()) {
|
||||
for (CanonicalType u : t.getProfile()) {
|
||||
types.add(builder.makeType(t, u));
|
||||
|
@ -32,13 +31,18 @@ public class PEDefinitionTypeSlice extends PEDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children) {
|
||||
children.addAll(builder.listChildren(baseStructure, baseDefinition, profileStructure, profiledDefinition, typeUrl));
|
||||
protected void makeChildren(String typeUrl, List<PEDefinition> children, boolean allFixed) {
|
||||
children.addAll(builder.listChildren(allFixed, this, profile, definition, typeUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirpath() {
|
||||
throw new Error("Not done yet");
|
||||
String base = definition.getName().replace("[x]", "");
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" | ");
|
||||
for (TypeRefComponent t : definition.getType()) {
|
||||
b.append(base+".ofType("+t.getWorkingCode()+")");
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.hl7.fhir.r5.profilemodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
@ -20,22 +21,36 @@ public abstract class PEInstance {
|
|||
/**
|
||||
* @return definition information about this instance data
|
||||
*/
|
||||
public abstract PEDefinition definition();
|
||||
public PEDefinition definition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type of this element
|
||||
*/
|
||||
public abstract PEType type();
|
||||
public PEType type() {
|
||||
return definition.types().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the children of this instance data
|
||||
*/
|
||||
public abstract List<PEInstance> children();
|
||||
public List<PEInstance> children() {
|
||||
List<PEInstance> res = new ArrayList<>();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the children of this instance data for the named property
|
||||
*/
|
||||
public abstract List<PEInstance> children(String name);
|
||||
public List<PEInstance> children(String name) {
|
||||
// PEDefinition child = definition.childByName(name);
|
||||
// if (child = null) {
|
||||
//
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the children of this instance data with the named property and the named type (for polymorphic
|
||||
|
|
|
@ -4,7 +4,9 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.Observation;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.profilemodel.PEDefinition;
|
||||
import org.hl7.fhir.r5.profilemodel.PEType;
|
||||
|
@ -32,7 +34,7 @@ public class PETests {
|
|||
|
||||
ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("R5", "profiles", "pe-extension-simple.json")));
|
||||
ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("R5", "profiles", "pe-extension-complex.json")));
|
||||
// ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("R5", "profiles", "pe-profile2.json")));
|
||||
ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("R5", "profiles", "pe-profile2.json")));
|
||||
ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("R5", "profiles", "pe-profile1.json")));
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +43,7 @@ public class PETests {
|
|||
@Test
|
||||
public void testProfile() throws IOException {
|
||||
load();
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.EXTENSION).buildPEDefinition("http://hl7.org/fhir/test/StructureDefinition/pe-profile1");
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.EXTENSION, true).buildPEDefinition("http://hl7.org/fhir/test/StructureDefinition/pe-profile1");
|
||||
|
||||
Assertions.assertEquals("TestProfile", pe.name());
|
||||
Assertions.assertEquals("Observation", pe.schemaName());
|
||||
|
@ -54,50 +56,69 @@ public class PETests {
|
|||
Assertions.assertEquals("Test Observation Profile", pe.shortDocumentation());
|
||||
Assertions.assertEquals("Test Observation Profile.", pe.documentation());
|
||||
|
||||
|
||||
List<PEDefinition> children = pe.children("Observation");
|
||||
|
||||
checkElement(pe, "Observation", "TestProfile", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/test/StructureDefinition/pe-profile1", 16);
|
||||
checkElement(children.get(0), "id", "id", 0, 1, null, 0);
|
||||
checkElement(children.get(1), "meta", "meta", 0, 1, "http://hl7.org/fhir/StructureDefinition/Meta", 7);
|
||||
checkElement(children.get(2), "language", "language", 0, 1, "http://hl7.org/fhir/StructureDefinition/code", 2);
|
||||
checkElement(children.get(3), "text", "text", 0, 1, "http://hl7.org/fhir/StructureDefinition/Narrative", 3);
|
||||
checkElement(children.get(4), "contained", "contained", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/Resource", 4);
|
||||
checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/Extension", 3);
|
||||
checkElement(children.get(6), "extension", "simple", 0, 1, "http://hl7.org/fhir/StructureDefinition/code", 2);
|
||||
checkElement(children.get(7), "extension", "complex", 0, 1, "http://hl7.org/fhir/StructureDefinition/Extension", 4);
|
||||
checkElement(children.get(8), "identifier", "identifier", 0, 1, "http://hl7.org/fhir/StructureDefinition/Identifier", 7);
|
||||
checkElement(children.get(9), "category", "category", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3);
|
||||
checkElement(children.get(10), "subject", "subject", 1, 1, "http://hl7.org/fhir/StructureDefinition/Reference", 5);
|
||||
checkElement(children.get(11), "encounter", "encounter", 0, 1, "http://hl7.org/fhir/StructureDefinition/Reference", 5);
|
||||
checkElement(children.get(12), "effective[x]", "effective[x]", 1, 1, "http://hl7.org/fhir/StructureDefinition/dateTime", 2);
|
||||
checkElement(children.get(13), "issued", "issued", 0, 1, "http://hl7.org/fhir/StructureDefinition/instant", 2);
|
||||
checkElement(children.get(14), "performer", "performer", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/Reference", 5);
|
||||
checkElement(children.get(15), "value[x]", "valueCodeableConcept", 0, 1, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3);
|
||||
|
||||
List<PEDefinition> gchildren = children.get(7).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
||||
checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/Extension", 3);
|
||||
checkElement(gchildren.get(1), "extension", "slice1", 0, 2, "http://hl7.org/fhir/StructureDefinition/Coding", 6);
|
||||
checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/string", 2);
|
||||
checkElement(gchildren.get(3), "extension", "slice3", 1, 1, "http://hl7.org/fhir/StructureDefinition/Extension", 3);
|
||||
checkElement(pe, "Observation", "TestProfile", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/test/StructureDefinition/pe-profile1", 18, "Observation");
|
||||
checkElement(children.get(0), "id", "id", 0, 1, false, null, 0, "id");
|
||||
checkElement(children.get(1), "meta", "meta", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Meta", 7, "meta");
|
||||
checkElement(children.get(2), "language", "language", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "language");
|
||||
checkElement(children.get(3), "text", "text", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Narrative", 3, "text");
|
||||
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(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(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(10), "category", "category", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category");
|
||||
checkElement(children.get(11), "code", "code", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "code");
|
||||
checkElement(children.get(12), "subject", "subject", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Reference", 5, "subject");
|
||||
checkElement(children.get(13), "encounter", "encounter", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Reference", 5, "encounter");
|
||||
checkElement(children.get(14), "effective[x]", "effective[x]", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/dateTime", 2, "effective");
|
||||
checkElement(children.get(15), "issued", "issued", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/instant", 2, "issued");
|
||||
checkElement(children.get(16), "performer", "performer", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Reference", 5, "performer");
|
||||
checkElement(children.get(17), "value[x]", "valueCodeableConcept", 0, 1, false, "http://hl7.org/fhir/test/StructureDefinition/pe-profile2", 4, "value.ofType(CodeableConcept)");
|
||||
|
||||
List<PEDefinition> ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
||||
checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/Extension", 3);
|
||||
checkElement(ggchildren.get(1), "extension", "slice3a", 0, 2, "http://hl7.org/fhir/StructureDefinition/Coding", 6);
|
||||
checkElement(ggchildren.get(2), "extension", "slice3b", 0, Integer.MAX_VALUE, "http://hl7.org/fhir/StructureDefinition/string", 2);
|
||||
List<PEDefinition> gchildren = children.get(11).children();
|
||||
checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, true, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||
checkElement(gchildren.get(1), "coding", "coding", 0, Integer.MAX_VALUE, true, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "coding");
|
||||
checkElement(gchildren.get(2), "text", "text", 0, 1, true, "http://hl7.org/fhir/StructureDefinition/string", 2, "text");
|
||||
|
||||
|
||||
gchildren = children.get(17).children("http://hl7.org/fhir/test/StructureDefinition/pe-profile2");
|
||||
checkElement(gchildren.get(0), "coding", "coding", 1, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "coding.where(((system = 'http://snomed.info/sct') or (system = 'http://loinc.org')).not())");
|
||||
checkElement(gchildren.get(1), "coding", "snomedct", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Coding", 5, "coding.where(system = 'http://snomed.info/sct')");
|
||||
checkElement(gchildren.get(2), "coding", "loinc", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Coding", 5, "coding.where(system = 'http://loinc.org')");
|
||||
checkElement(gchildren.get(3), "text", "text", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "text");
|
||||
|
||||
List<PEDefinition> ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/string");
|
||||
checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||
checkElement(ggchildren.get(1), "value", "value", 1, 1, false, null, 3, "value");
|
||||
|
||||
gchildren = children.get(7).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
||||
checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||
checkElement(gchildren.get(1), "extension", "slice1", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice1').value");
|
||||
checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice2').value");
|
||||
checkElement(gchildren.get(3), "extension", "slice3", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension('slice3').extension");
|
||||
|
||||
ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/Extension");
|
||||
checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension");
|
||||
checkElement(ggchildren.get(1), "extension", "slice3a", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice3a').value");
|
||||
checkElement(ggchildren.get(2), "extension", "slice3b", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice3b').value");
|
||||
}
|
||||
|
||||
private void checkElement(PEDefinition pe, String schemaName, String name, int min, int max, String type, int children) {
|
||||
private void checkElement(PEDefinition pe, String schemaName, String name, int min, int max, boolean fixed, String type, int children, String fhirpath) {
|
||||
Assertions.assertEquals(name, pe.name());
|
||||
Assertions.assertEquals(schemaName, pe.schemaName());
|
||||
Assertions.assertEquals(min, pe.min());
|
||||
Assertions.assertEquals(max, pe.max());
|
||||
Assertions.assertEquals(fixed, pe.fixedValue() || pe.isInFixedValue());
|
||||
if (type != null) {
|
||||
Assertions.assertEquals(1, pe.types().size());
|
||||
Assertions.assertEquals(type, pe.types().get(0).getUrl());
|
||||
List<PEDefinition> children2 = pe.children(type);
|
||||
Assertions.assertEquals(children, children2.size());
|
||||
}
|
||||
Assertions.assertEquals(fhirpath, pe.fhirpath());
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,7 +126,7 @@ public class PETests {
|
|||
public void testUSPatientCore() throws IOException {
|
||||
load();
|
||||
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.EXTENSION_ID).buildPEDefinition("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient");
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.EXTENSION_ID, false).buildPEDefinition("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient");
|
||||
|
||||
Assertions.assertEquals("USCorePatientProfile", pe.name());
|
||||
Assertions.assertEquals("Patient", pe.schemaName());
|
||||
|
@ -243,7 +264,7 @@ public class PETests {
|
|||
public void dumpUSPatientCore() throws IOException {
|
||||
load();
|
||||
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.NONE).buildPEDefinition("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient");
|
||||
PEDefinition pe = new PEBuilder(ctxt, PEElementPropertiesPolicy.NONE, false).buildPEDefinition("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient");
|
||||
dump(pe, "");
|
||||
}
|
||||
|
||||
|
@ -266,4 +287,18 @@ public class PETests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreate() throws IOException {
|
||||
load();
|
||||
|
||||
Observation res = (Observation) new PEBuilder(ctxt, PEElementPropertiesPolicy.NONE, false).createResource("http://hl7.org/fhir/test/StructureDefinition/pe-profile1", true);
|
||||
Assertions.assertEquals("http://hl7.org/fhir/test/StructureDefinition/pe-profile1", res.getMeta().getProfile().get(0).primitiveValue());
|
||||
Assertions.assertEquals("final", res.getStatusElement().asStringValue());
|
||||
Assertions.assertEquals("76690-7", res.getCode().getCodingFirstRep().getCode());
|
||||
|
||||
String json = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(res);
|
||||
System.out.println(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue