use of org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent in project org.hl7.fhir.core by hapifhir.
the class CSVWriter method itemList.
private String itemList(List l) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < l.size(); i++) {
Object o = l.get(i);
String val = "";
if (o instanceof StringType) {
val = ((StringType) o).getValue();
} else if (o instanceof UriType) {
val = ((UriType) o).getValue();
} else if (o instanceof IdType) {
val = ((IdType) o).getValue();
} else if (o instanceof Enumeration<?>) {
val = o.toString();
} else if (o instanceof TypeRefComponent) {
TypeRefComponent t = (TypeRefComponent) o;
val = t.getCode() + (t.getProfile() == null ? "" : " {" + t.getProfile() + "}") + (t.getTargetProfile() == null ? "" : " {" + t.getTargetProfile() + "}") + (t.getAggregation() == null || t.getAggregation().isEmpty() ? "" : " (" + itemList(t.getAggregation()) + ")");
} else if (o instanceof Coding) {
Coding t = (Coding) o;
val = (t.getSystem() == null ? "" : t.getSystem()) + (t.getCode() == null ? "" : "#" + t.getCode()) + (t.getDisplay() == null ? "" : " (" + t.getDisplay() + ")");
} else if (o instanceof ElementDefinitionConstraintComponent) {
ElementDefinitionConstraintComponent c = (ElementDefinitionConstraintComponent) o;
val = c.getKey() + ":" + c.getHuman() + " {" + c.getExpression() + "}";
} else if (o instanceof ElementDefinitionSlicingDiscriminatorComponent) {
ElementDefinitionSlicingDiscriminatorComponent c = (ElementDefinitionSlicingDiscriminatorComponent) o;
val = c.getType().toCode() + ":" + c.getPath() + "}";
} else {
val = o.toString();
val = val.substring(val.indexOf("[") + 1);
val = val.substring(0, val.indexOf("]"));
}
s = s.append(val);
if (i == 0)
s.append("\n");
}
return s.toString();
}
use of org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent in project org.hl7.fhir.core by hapifhir.
the class FHIRPathEngine method getChildTypesByName.
private void getChildTypesByName(String type, String name, TypeDetails result, ExpressionNode expr) throws PathEngineException, DefinitionException {
if (Utilities.noString(type))
throw new PathEngineException("No type provided in BuildToolPathEvaluator.getChildTypesByName", expr.getStart(), expr.toString());
if (type.equals("http://hl7.org/fhir/StructureDefinition/xhtml"))
return;
if (type.startsWith(Constants.NS_SYSTEM_TYPE))
return;
if (type.equals(TypeDetails.FP_SimpleTypeInfo)) {
getSimpleTypeChildTypesByName(name, result);
} else if (type.equals(TypeDetails.FP_ClassInfo)) {
getClassInfoChildTypesByName(name, result);
} else {
String url = null;
if (type.contains("#")) {
url = type.substring(0, type.indexOf("#"));
} else {
url = type;
}
String tail = "";
StructureDefinition sd = worker.fetchResource(StructureDefinition.class, url);
if (sd == null)
// this really is an error, because we can only get to here if the internal infrastrucgture is wrong
throw new DefinitionException("Unknown type " + type);
List<StructureDefinition> sdl = new ArrayList<StructureDefinition>();
ElementDefinitionMatch m = null;
if (type.contains("#"))
m = getElementDefinition(sd, type.substring(type.indexOf("#") + 1), false, expr);
if (m != null && hasDataType(m.definition)) {
if (m.fixedType != null) {
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, worker.getOverrideVersionNs()));
if (dt == null)
throw new DefinitionException("unknown data type " + m.fixedType);
sdl.add(dt);
} else
for (TypeRefComponent t : m.definition.getType()) {
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(t.getCode(), worker.getOverrideVersionNs()));
if (dt == null)
throw new DefinitionException("unknown data type " + t.getCode());
sdl.add(dt);
}
} else {
sdl.add(sd);
if (type.contains("#")) {
tail = type.substring(type.indexOf("#") + 1);
tail = tail.substring(tail.indexOf("."));
}
}
for (StructureDefinition sdi : sdl) {
String path = sdi.getSnapshot().getElement().get(0).getPath() + tail + ".";
if (name.equals("**")) {
assert (result.getCollectionStatus() == CollectionStatus.UNORDERED);
for (ElementDefinition ed : sdi.getSnapshot().getElement()) {
if (ed.getPath().startsWith(path))
for (TypeRefComponent t : ed.getType()) {
if (t.hasCode() && t.getCodeElement().hasValue()) {
String tn = null;
if (t.getCode().equals("Element") || t.getCode().equals("BackboneElement"))
tn = sdi.getType() + "#" + ed.getPath();
else
tn = t.getCode();
if (t.getCode().equals("Resource")) {
for (String rn : worker.getResourceNames()) {
if (!result.hasType(worker, rn)) {
getChildTypesByName(result.addType(rn), "**", result, expr);
}
}
} else if (!result.hasType(worker, tn)) {
getChildTypesByName(result.addType(tn), "**", result, expr);
}
}
}
}
} else if (name.equals("*")) {
assert (result.getCollectionStatus() == CollectionStatus.UNORDERED);
for (ElementDefinition ed : sdi.getSnapshot().getElement()) {
if (ed.getPath().startsWith(path) && !ed.getPath().substring(path.length()).contains("."))
for (TypeRefComponent t : ed.getType()) {
if (// Element.id or Extension.url
Utilities.noString(t.getCode()))
result.addType("System.string");
else if (t.getCode().equals("Element") || t.getCode().equals("BackboneElement"))
result.addType(sdi.getType() + "#" + ed.getPath());
else if (t.getCode().equals("Resource"))
result.addTypes(worker.getResourceNames());
else
result.addType(t.getCode());
}
}
} else {
path = sdi.getSnapshot().getElement().get(0).getPath() + tail + "." + name;
ElementDefinitionMatch ed = getElementDefinition(sdi, path, false, expr);
if (ed != null) {
if (!Utilities.noString(ed.getFixedType()))
result.addType(ed.getFixedType());
else
for (TypeRefComponent t : ed.getDefinition().getType()) {
if (Utilities.noString(t.getCode())) {
if (Utilities.existsInList(ed.getDefinition().getId(), "Element.id", "Extension.url") || Utilities.existsInList(ed.getDefinition().getBase().getPath(), "Resource.id", "Element.id", "Extension.url"))
result.addType(TypeDetails.FP_NS, "string");
// throw new PathEngineException("Illegal reference to primitive value attribute @ "+path);
break;
}
ProfiledType pt = null;
if (t.getCode().equals("Element") || t.getCode().equals("BackboneElement"))
pt = new ProfiledType(sdi.getUrl() + "#" + path);
else if (t.getCode().equals("Resource"))
result.addTypes(worker.getResourceNames());
else
pt = new ProfiledType(t.getCode());
if (pt != null) {
if (t.hasProfile())
pt.addProfiles(t.getProfile());
if (ed.getDefinition().hasBinding())
pt.addBinding(ed.getDefinition().getBinding());
result.addType(pt);
}
}
}
}
}
}
}
use of org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent in project org.hl7.fhir.core by hapifhir.
the class GraphQLSchemaGenerator method generateProperties.
private void generateProperties(List<StringBuilder> list, StringBuilder b, String typeName, StructureDefinition sd, ElementDefinition ed, String mode, String suffix) throws IOException {
List<ElementDefinition> children = ProfileUtilities.getChildList(sd, ed);
for (ElementDefinition child : children) {
if (child.hasContentReference()) {
ElementDefinition ref = resolveContentReference(sd, child.getContentReference());
generateProperty(list, b, typeName, sd, child, ref.getType().get(0), false, ref, mode, suffix);
} else if (child.getType().size() == 1) {
generateProperty(list, b, typeName, sd, child, child.getType().get(0), false, null, mode, suffix);
} else {
boolean ref = false;
for (TypeRefComponent t : child.getType()) {
if (!t.hasTarget())
generateProperty(list, b, typeName, sd, child, t, true, null, mode, suffix);
else if (!ref) {
ref = true;
generateProperty(list, b, typeName, sd, child, t, true, null, mode, suffix);
}
}
}
}
}
use of org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method generateSnapshot.
/**
* Given a base (snapshot) profile structure, and a differential profile, generate a new snapshot profile
*
* @param base - the base structure on which the differential will be applied
* @param differential - the differential to apply to the base
* @param url - where the base has relative urls for profile references, these need to be converted to absolutes by prepending this URL (e.g. the canonical URL)
* @param webUrl - where the base has relative urls in markdown, these need to be converted to absolutes by prepending this URL (this is not the same as the canonical URL)
* @param trimDifferential - if this is true, then the snap short generator will remove any material in the element definitions that is not different to the base
* @return
* @throws FHIRException
* @throws DefinitionException
* @throws Exception
*/
public void generateSnapshot(StructureDefinition base, StructureDefinition derived, String url, String webUrl, String profileName) throws DefinitionException, FHIRException {
if (base == null) {
throw new DefinitionException(context.formatMessage(I18nConstants.NO_BASE_PROFILE_PROVIDED));
}
if (derived == null) {
throw new DefinitionException(context.formatMessage(I18nConstants.NO_DERIVED_STRUCTURE_PROVIDED));
}
checkNotGenerating(base, "Base for generating a snapshot for the profile " + derived.getUrl());
checkNotGenerating(derived, "Focus for generating a snapshot");
if (!base.hasType()) {
throw new DefinitionException(context.formatMessage(I18nConstants.BASE_PROFILE__HAS_NO_TYPE, base.getUrl()));
}
if (!derived.hasType()) {
throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_TYPE, derived.getUrl()));
}
if (!derived.hasDerivation()) {
throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_DERIVATION_VALUE_AND_SO_CANT_BE_PROCESSED, derived.getUrl()));
}
if (!base.getType().equals(derived.getType()) && derived.getDerivation() == TypeDerivationRule.CONSTRAINT) {
throw new DefinitionException(context.formatMessage(I18nConstants.BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___, base.getUrl(), base.getType(), derived.getUrl(), derived.getType()));
}
if (snapshotStack.contains(derived.getUrl())) {
throw new DefinitionException(context.formatMessage(I18nConstants.CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__, snapshotStack.toString()));
}
derived.setUserData("profileutils.snapshot.generating", true);
snapshotStack.add(derived.getUrl());
try {
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
webUrl = webUrl + '/';
if (defWebRoot == null)
defWebRoot = webUrl;
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
try {
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
checkDifferentialBaseType(derived);
// so we have two lists - the base list, and the differential list
// the differential list is only allowed to include things that are in the base list, but
// is allowed to include them multiple times - thereby slicing them
// our approach is to walk through the base list, and see whether the differential
// says anything about them.
int baseCursor = 0;
// we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
int diffCursor = 0;
for (ElementDefinition e : derived.getDifferential().getElement()) e.clearUserData(GENERATED_IN_SNAPSHOT);
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
// we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential());
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
String derivedType = derived.getType();
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
derivedType = derivedType.substring(derivedType.lastIndexOf("/") + 1);
}
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
}
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
// debug = true;
// }
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size() - 1, derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size() - 1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, null, new ArrayList<ElementRedirection>(), base);
checkGroupConstraints(derived);
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
derived.getSnapshot().addElement(outcome);
}
}
}
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
updateMaps(base, derived);
setIds(derived, false);
if (debug) {
System.out.println("Differential: ");
for (ElementDefinition ed : derived.getDifferential().getElement()) System.out.println(" " + ed.getId() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
System.out.println("Snapshot: ");
for (ElementDefinition ed : derived.getSnapshot().getElement()) System.out.println(" " + ed.getId() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
}
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
// Check that all differential elements have a corresponding snapshot element
int ce = 0;
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData("diff-source"))
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
else {
if (e.hasUserData(DERIVATION_EQUALS))
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
if (e.hasUserData(DERIVATION_POINTER))
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
}
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
b.append(e.hasId() ? "id: " + e.getId() : "path: " + e.getPath());
ce++;
if (e.hasId()) {
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
}
}
}
if (!Utilities.noString(b.toString())) {
String msg = "The profile " + derived.getUrl() + " has " + ce + " " + Utilities.pluralize("element", ce) + " in the differential (" + b.toString() + ") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
System.out.println("Error in snapshot generation: " + msg);
if (!debug) {
System.out.println("Differential: ");
for (ElementDefinition ed : derived.getDifferential().getElement()) System.out.println(" " + ed.getId() + " = " + ed.getPath() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
System.out.println("Snapshot: ");
for (ElementDefinition ed : derived.getSnapshot().getElement()) System.out.println(" " + ed.getId() + " = " + ed.getPath() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
}
if (exception)
throw new DefinitionException(msg);
else
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
}
// hack around a problem in R4 definitions (somewhere?)
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
if (mm.hasMap()) {
mm.setMap(mm.getMap().trim());
}
}
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
if (s.hasSource()) {
String ref = s.getSource();
if (!Utilities.isAbsoluteUrl(ref)) {
if (ref.contains(".")) {
s.setSource("http://hl7.org/fhir/StructureDefinition/" + ref.substring(0, ref.indexOf(".")) + "#" + ref);
} else {
s.setSource("http://hl7.org/fhir/StructureDefinition/" + ref);
}
}
}
}
}
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
if (!ed.hasBase()) {
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
}
}
}
// last, check for wrong profiles or target profiles
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
for (TypeRefComponent t : ed.getType()) {
for (UriType u : t.getProfile()) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
if (sd == null) {
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
sd = xver.makeDefinition(u.getValue());
}
}
if (sd == null) {
if (messages != null) {
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + ed.getId(), "The type of profile " + u.getValue() + " cannot be checked as the profile is not known", IssueSeverity.WARNING));
}
} else {
String wt = t.getWorkingCode();
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
wt = "OperationOutcome";
}
if (!sd.getType().equals(wt)) {
boolean ok = isCompatibleType(wt, sd);
if (!ok) {
String smsg = "The profile " + u.getValue() + " has type " + sd.getType() + " which is not consistent with the stated type " + wt;
if (exception)
throw new DefinitionException(smsg);
else
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + ed.getId(), smsg, IssueSeverity.ERROR));
}
}
}
}
}
}
} catch (Exception e) {
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
derived.setSnapshot(null);
derived.clearUserData("profileutils.snapshot.generating");
throw e;
}
} finally {
derived.clearUserData("profileutils.snapshot.generating");
snapshotStack.remove(derived.getUrl());
}
}
use of org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method typeCode.
public static String typeCode(List<TypeRefComponent> types) {
StringBuilder b = new StringBuilder();
boolean first = true;
for (TypeRefComponent type : types) {
if (first)
first = false;
else
b.append(", ");
b.append(type.getWorkingCode());
if (type.hasTargetProfile())
b.append("{" + type.getTargetProfile() + "}");
else if (type.hasProfile())
b.append("{" + type.getProfile() + "}");
}
return b.toString();
}
Aggregations