use of org.hl7.fhir.r4.model.ValueSet in project kindling by HL7.
the class XSDGenerator method generateEnum.
private void generateEnum(String en) throws IOException {
if (allenums.contains(en))
return;
allenums.add(en);
write(" <xs:simpleType name=\"" + en + "-list\">\r\n");
write(" <xs:restriction base=\"code-primitive\">\r\n");
ValueSet vs = enums.get(en);
vs.setUserData(ToolResourceUtilities.NAME_VS_USE_MARKER, true);
ValueSet ex = workerContext.expandVS(vs, true, false).getValueset();
for (ValueSetExpansionContainsComponent cc : ex.getExpansion().getContains()) {
genIncludedCode(cc);
}
write(" </xs:restriction>\r\n");
write(" </xs:simpleType>\r\n");
write(" <xs:complexType name=\"" + en + "\">\r\n");
write(" <xs:annotation>\r\n");
write(" <xs:documentation xml:lang=\"en\">" + Utilities.escapeXml(enumDefs.get(en)) + "</xs:documentation>\r\n");
write(" <xs:documentation xml:lang=\"en\">If the element is present, it must have either a @value, an @id, or extensions</xs:documentation>\r\n");
write(" </xs:annotation>\r\n");
write(" <xs:complexContent>\r\n");
write(" <xs:extension base=\"Element\">\r\n");
write(" <xs:attribute name=\"value\" type=\"" + en + "-list\" use=\"optional\"/>\r\n");
write(" </xs:extension>\r\n");
write(" </xs:complexContent>\r\n");
write(" </xs:complexType>\r\n");
}
use of org.hl7.fhir.r4.model.ValueSet in project kindling by HL7.
the class JsonSpecGenerator method generateCoreElem.
@SuppressWarnings("rawtypes")
private void generateCoreElem(List<ElementDefinition> elements, ElementDefinition elem, int indent, String pathName, boolean asValue, TypeRefComponent type, boolean last, boolean complex) throws Exception {
if (elem.getPath().endsWith(".id"))
return;
if (!complex && elem.getPath().endsWith(".extension"))
return;
if (elem.getMax().equals("0"))
return;
String indentS = "";
for (int i = 0; i < indent; i++) {
indentS += " ";
}
write(indentS);
List<ElementDefinition> children = getChildren(elements, elem);
String name = tail(elem.getPath());
String en = asValue ? "value[x]" : name;
String tc = type.getWorkingCode();
if (en.contains("[x]"))
en = en.replace("[x]", upFirst(tc));
boolean unbounded = elem.hasMax() && elem.getMax().equals("*");
// 1. name
write("\"<a href=\"" + (defPage + "#" + pathName + "." + en) + "\" title=\"" + Utilities.escapeXml(getEnhancedDefinition(elem)) + "\" class=\"dict\"><span style=\"text-decoration: underline\">" + en + "</span></a>\" : ");
// 2. value
boolean delayedCloseArray = false;
if (unbounded)
write("[");
if (type == null) {
// inline definition
assert (children.size() > 0);
write("{");
delayedCloseArray = true;
} else if (definitions.getPrimitives().containsKey(tc)) {
if (!(tc.equals("integer") || tc.equals("boolean") || tc.equals("decimal")))
write("\"");
if (elem.hasFixed())
write(Utilities.escapeJson(((PrimitiveType) elem.getFixed()).asStringValue()));
else
write("<<span style=\"color: darkgreen\"><a href=\"" + prefix + (dtRoot + definitions.getSrcFile(tc) + ".html#" + tc) + "\">" + tc + "</a></span>>");
if (!(tc.equals("integer") || tc.equals("boolean") || tc.equals("decimal")))
write("\"");
} else {
write("{ ");
write("<span style=\"color: darkgreen\"><a href=\"" + prefix + (dtRoot + definitions.getSrcFile(tc) + ".html#" + tc) + "\">" + tc + "</a></span>");
if (type.hasProfile()) {
if (type.getProfile().get(0).getValue().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
String t = type.getProfile().get(0).getValue().substring(40);
if (definitions.hasType(t))
write("(<span style=\"color: darkgreen\"><a href=\"" + prefix + (dtRoot + definitions.getSrcFile(t) + ".html#" + t) + "\">" + t + "</a></span>)");
else if (definitions.hasResource(t))
write("(<span style=\"color: darkgreen\"><a href=\"" + prefix + dtRoot + t.toLowerCase() + ".html\">" + t + "</a></span>)");
else
write("(" + t + ")");
} else
write("(" + type.getProfile() + ")");
}
if (type.hasTargetProfile()) {
if (type.getTargetProfile().get(0).getValue().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
String t = type.getTargetProfile().get(0).getValue().substring(40);
if (definitions.hasType(t))
write("(<span style=\"color: darkgreen\"><a href=\"" + prefix + (dtRoot + definitions.getSrcFile(t) + ".html#" + t) + "\">" + t + "</a></span>)");
else if (definitions.hasResource(t))
write("(<span style=\"color: darkgreen\"><a href=\"" + prefix + dtRoot + t.toLowerCase() + ".html\">" + t + "</a></span>)");
else
write("(" + t + ")");
} else
write("(" + type.getTargetProfile() + ")");
}
write(" }");
}
if (!delayedCloseArray) {
if (unbounded)
write("]");
if (!last)
write(",");
}
write(" <span style=\"color: Gray\">//</span>");
// 3. optionality
writeCardinality(elem);
// 4. doco
if (!elem.hasFixed()) {
if (elem.hasBinding() && elem.getBinding().hasValueSet()) {
ValueSet vs = resolveValueSet(elem.getBinding().getValueSet());
if (vs != null)
write("<span style=\"color: navy; opacity: 0.8\"><a href=\"" + (Utilities.isAbsoluteUrl(vs.getUserString("path")) ? "" : prefix) + vs.getUserData("path") + "\" style=\"color: navy\">" + Utilities.escapeXml(elem.getShort()) + "</a></span>");
else
write("<span style=\"color: navy; opacity: 0.8\"><a href=\"" + elem.getBinding().getValueSet() + ".html\" style=\"color: navy\">" + Utilities.escapeXml(elem.getShort()) + "</a></span>");
} else
write("<span style=\"color: navy; opacity: 0.8\">" + Utilities.escapeXml(elem.getShort()) + "</span>");
}
write("\r\n");
if (delayedCloseArray) {
int c = 0;
for (ElementDefinition child : children) {
if (child.getType().size() == 1)
generateCoreElem(elements, child, indent + 1, pathName + "." + name, false, child.getType().get(0), ++c == children.size(), false);
else {
write("<span style=\"color: Gray\">// value[x]: <span style=\"color: navy; opacity: 0.8\">" + Utilities.escapeXml(child.getShort()) + "</span>. One of these " + Integer.toString(child.getType().size()) + ":</span>\r\n");
for (TypeRefComponent t : child.getType()) generateCoreElem(elements, child, indent + 1, pathName + "." + name, false, t, ++c == children.size(), false);
}
}
write("}]");
if (!last)
write(",");
}
}
use of org.hl7.fhir.r4.model.ValueSet in project kindling by HL7.
the class ProfileGenerator method convertElements.
public void convertElements(ElementDefn src, StructureDefinition ed, String path) throws Exception {
ElementDefinition dst = new ElementDefinition();
if (!ed.hasDifferential())
ed.setDifferential(new StructureDefinitionDifferentialComponent());
ed.getDifferential().getElement().add(dst);
String thisPath = path == null ? "Extension" : path;
dst.setId(thisPath);
dst.setPath(thisPath);
if (!Utilities.noString(src.getProfileName()))
dst.setSliceName(src.getProfileName());
dst.setShort(src.getShortDefn());
dst.setDefinition(preProcessMarkdown(src.getDefinition(), "Element Definition"));
dst.setComment(preProcessMarkdown(src.getComments(), "Element Comments"));
if (src.getMaxCardinality() != null) {
if (src.getMaxCardinality() == Integer.MAX_VALUE)
dst.setMax("*");
else
dst.setMax(src.getMaxCardinality().toString());
}
if (src.getMinCardinality() != null)
dst.setMin(src.getMinCardinality());
if (src.getFixed() != null)
dst.setFixed(src.getFixed());
if (src.hasMustSupport())
dst.setMustSupport(src.isMustSupport());
if (src.hasModifier())
dst.setIsModifier(src.isModifier());
if (dst.getIsModifier())
dst.setIsModifierReason(src.getModifierReason());
if (src.hasSummaryItem() && dst.getPath().contains("."))
dst.setIsSummaryElement(Factory.newBoolean(src.isSummary()));
for (Invariant id : src.getStatedInvariants()) dst.addCondition(id.getId());
// dDst.
for (TypeRef t : src.getTypes()) {
if (t.hasParams()) {
for (String tp : t.getParams()) {
if (definitions.hasLogicalModel(tp)) {
for (String tpn : definitions.getLogicalModel(tp).getImplementations()) {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
String pr = "http://hl7.org/fhir/StructureDefinition/" + tpn;
type.addTargetProfile(pr);
}
} else {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
String pr = t.hasProfile() ? t.getProfile() : // this should only happen if t.getParams().size() == 1
"http://hl7.org/fhir/StructureDefinition/" + (tp.equals("Any") ? "Resource" : tp);
if (type.getWorkingCode().equals("Reference") || type.getWorkingCode().equals("canonical") || type.getWorkingCode().equals("CodeableReference"))
type.addTargetProfile(pr);
else
type.addProfile(pr);
}
}
} else if (t.isWildcardType()) {
for (String n : TypesUtilities.wildcardTypes(version.toString())) dst.getType(n);
} else {
if (definitions != null && definitions.getConstraints().containsKey(t.getName())) {
ProfiledType ct = definitions.getConstraints().get(t.getName());
ElementDefinition.TypeRefComponent type = dst.getType(ct.getBaseType());
type.addProfile("http://hl7.org/fhir/StructureDefinition/" + ct.getName());
} else if ("Extension.url".equals(path)) {
// juat don't populate it
// ElementDefinition.TypeRefComponent tt = dst.addType();
// tt.setCodeElement(new UriType());
// tt.getFormatCommentsPre().add("Note: special primitive values do not have an assigned type. e.g. this is compiler magic. XML, JSON and RDF types provided by extension");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_JSON_TYPE, "string");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_XML_TYPE, "xs:anyURI");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_RDF_TYPE, "xs:anyURI");
} else {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
if (t.hasProfile())
if (type.getWorkingCode().equals("Reference") || type.getWorkingCode().equals("CodeableReference"))
type.addTargetProfile(t.getProfile());
else
type.addProfile(t.getProfile());
}
}
}
if (definitions != null) {
// igtodo - catch this
for (String mu : definitions.getMapTypes().keySet()) {
if (src.hasMapping(mu)) {
addMapping(ed, dst, mu, src.getMapping(mu), null);
}
}
}
for (String in : src.getInvariants().keySet()) {
ElementDefinitionConstraintComponent con = new ElementDefinitionConstraintComponent();
Invariant inv = src.getInvariants().get(in);
con.setKey(inv.getId());
if (!con.hasKey()) {
extensionCounter++;
con.setKey("exd-" + Integer.toString(extensionCounter));
}
con.setRequirements(inv.getRequirements());
if (Utilities.noString(inv.getSeverity()))
con.setSeverity(ConstraintSeverity.ERROR);
else
con.setSeverity(ConstraintSeverity.fromCode(inv.getSeverity()));
con.setHuman(inv.getEnglish());
con.setXpath(inv.getXpath());
if (!"n/a".equals(inv.getExpression()))
con.setExpression(inv.getExpression());
dst.getConstraint().add(con);
}
if (src.hasBinding())
dst.setBinding(generateBinding(src.getBinding()));
if (src.getElements().isEmpty()) {
if (path == null)
throw new Exception("?error parsing extension");
} else {
ElementDefn url = src.getElements().get(0);
if (!url.getName().equals("url"))
throw new Exception("first child of extension should be 'url', not " + url.getName() + " for structure definition " + ed.getUrl());
convertElements(url, ed, thisPath + ".url");
// this pair might leave elements out of order, but we're going to sort them later
if (!hasValue(src)) {
ElementDefn value = new ElementDefn();
value.setName("value[x]");
value.setMinCardinality(0);
value.setMaxCardinality(0);
convertElements(value, ed, thisPath + ".value[x]");
} else {
ElementDefn ext = new ElementDefn();
// can't have an extension if you have a value
ext.setName("extension");
ext.setMaxCardinality(0);
convertElements(ext, ed, thisPath + ".extension");
}
if (src.getElements().size() == 2 && src.getElements().get(0).getName().equals("url") && src.getElements().get(1).getName().equals("value[x]")) {
ElementDefn value = src.getElements().get(1);
value.setMinCardinality(1);
convertElements(value, ed, thisPath + ".value[x]");
} else {
for (ElementDefn child : src.getElements()) {
if (child != url) {
if (child.getName().startsWith("value") && !child.getName().startsWith("valueSet"))
convertElements(child, ed, thisPath + "." + child.getName());
else {
if (child.getElements().size() == 0 || !child.getElements().get(0).getName().equals("url")) {
ElementDefn childUrl = new ElementDefn();
childUrl.setName("url");
childUrl.setXmlAttribute(true);
childUrl.getTypes().add(new TypeRef("uri"));
childUrl.setFixed(new UriType(child.getName()));
child.getElements().add(0, childUrl);
}
if (!hasValue(child)) {
ElementDefn value = new ElementDefn();
value.setName("value[x]");
value.setMinCardinality(0);
value.setMaxCardinality(0);
child.getElements().add(value);
}
convertElements(child, ed, thisPath + ".extension");
}
}
}
}
}
}
use of org.hl7.fhir.r4.model.ValueSet in project kindling by HL7.
the class ResourceDependencyGenerator method addBindingToAnalysis.
private void addBindingToAnalysis(HierarchicalTableGenerator gen, Row row, Cell dc, boolean req, StandardsStatus elementStatus, BindingSpecification binding) throws FHIRException {
String tgtFMM = null;
StandardsStatus tgtSS = null;
ValueSet vs = binding.getValueSet();
if (vs != null) {
tgtFMM = ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_FMM_LEVEL);
tgtSS = ToolingExtensions.getStandardsStatus(vs);
} else if (Utilities.existsInList(binding.getReference(), "http://www.rfc-editor.org/bcp/bcp13.txt")) {
tgtFMM = "5";
tgtSS = StandardsStatus.EXTERNAL;
}
if (elementStatus == null)
elementStatus = sstatus;
if (tgtFMM == null)
addError(gen, row, dc, "Binding Error: Unable to resolve vs '" + binding.getReference() + "' to check dependencies", null);
else {
boolean ok = elementStatus.canDependOn(tgtSS);
if (ok)
ok = fmm.compareTo(tgtFMM) <= 0;
if (ok)
// addInfo(gen, row, dc, "Binding OK (ValueSet = FMM"+tgtFMM+"-"+tgtSS.toDisplay()+" vs. Element = FMM"+fmm+"-"+elementStatus.toDisplay()+")", null);
;
else
addError(gen, row, dc, "Binding Error: (ValueSet = FMM" + tgtFMM + "-" + tgtSS.toDisplay() + " vs. Element = FMM" + fmm + "-" + elementStatus.toDisplay() + ")", vs.getUserString("path"));
}
}
use of org.hl7.fhir.r4.model.ValueSet in project health-patterns by LinuxForHealth.
the class TerminologyService method translateResource.
/**
* Translates the given single FHIR resource represented as a {@link JsonNode}.
*
* @param resource the FHIR resource to translate
* @returns true if there was something to translate, false otherwise
* @throws DeIdentifierException if there is an error in the de-identification REST API or parsing the JSON
* @throws IllegalArgumentException if the given JSON does not have a 'resource' object
*/
private boolean translateResource(JsonNode resource) {
boolean translatedSomething = false;
String resourceType = getResourceType(resource);
boolean isTranslatable = StringUtils.equalsAny(resourceType, TRANSLATABLE_FHIR_TYPES);
if (!isTranslatable) {
return translatedSomething;
}
ArrayNode extensions = (ArrayNode) resource.get(EXTENSION_OBJECT);
if (extensions == null) {
return translatedSomething;
}
for (int i = 0; i < extensions.size(); i++) {
JsonNode extension = extensions.get(i);
JsonNode urlJson = extension.get(URL_OBJECT);
JsonNode valueCodeJson = extension.get(VALUE_CODE_OBJECT);
if (urlJson == null || valueCodeJson == null) {
// In order to do a translation we need both the url and the valueCode
continue;
}
// The resource's extension URL is the URL for the StructureDefinition, so we resolve a ValueSet if known
String structureDefinitionURL = urlJson.asText();
String valueSetURL = valueSetForStructureDefinition.get(structureDefinitionURL);
// and if known we check the FHIR Server's known ConceptMaps to see if there is a corresponding one
// http://4603f72b-us-south.lb.appdomain.cloud/fhir-server/api/v4/ConceptMap?_format=json&source-uri=http://hl7.org/fhir/us/core/ValueSet/birthsex
Bundle bundle = fhirClient.search().forResource(ConceptMap.class).where(ConceptMap.SOURCE_URI.hasId(valueSetURL)).returnBundle(Bundle.class).execute();
String conceptMapId;
if (!bundle.getEntry().isEmpty()) {
Resource conceptMap = bundle.getEntry().get(0).getResource();
if (bundle.getEntry().size() > 1) {
System.err.println("Found multiple ConceptMaps that will map " + valueSetURL + " for this StructureDefinition, will use the first one " + conceptMap.getId());
} else {
System.out.println("Found ConceptMap for " + valueSetURL + ": " + conceptMap.getId() + " !!");
}
conceptMapId = conceptMap.getIdElement().getIdPart();
} else {
System.out.println("Did not find ConceptMap for " + valueSetURL + "!!");
continue;
}
// "POST ${FHIR_URL}/${conceptMapID}/$translate?code=${code}&system=${valueSet}&_format=json
String valueCode = valueCodeJson.asText();
String url = String.format("%s/ConceptMap/%s/$translate?code=%s&system=%s&_format=json", fhirClient.getServerBase(), conceptMapId, valueCode, valueSetURL);
Parameters translationResponse = fhirClient.fetchResourceFromUrl(Parameters.class, url);
// This is what comes back from the server
// {
// "resourceType": "Parameters",
// "parameter": [
// {
// "name": "result",
// "valueBoolean": true
// },
// {
// "name": "match",
// "part": [
// {
// "name": "equivalence",
// "valueCode": "equivalent"
// },
// {
// "name": "concept",
// "valueCoding": {
// "system": "http://ibm.com/fhir/cdm/ValueSet/sex-assigned-at-birth",
// "code": "male",
// "display": "Male"
// }
// }
// ]
// }
// ]
// }
Coding translatedCode = null;
List<ParametersParameterComponent> parameters = translationResponse.getParameter();
for (ParametersParameterComponent parameter : parameters) {
if (parameter.getName().equals(MATCH_VALUE)) {
List<ParametersParameterComponent> parts = parameter.getPart();
for (ParametersParameterComponent part : parts) {
if (part.getName().equals(CONCEPT_VALUE)) {
try {
translatedCode = (Coding) part.getValue();
} catch (ClassCastException e) {
String jsonResponse = fhirClient.getFhirContext().newJsonParser().encodeResourceToString(translationResponse);
System.err.println("Found a ConceptMap that will map " + valueSetURL + " for this StructureDefinition, but the FHIR server returned an unknown $translate response (expected a 'valueCoding' part): " + jsonResponse);
}
}
}
}
}
if (translatedCode == null) {
String jsonResponse = fhirClient.getFhirContext().newJsonParser().encodeResourceToString(translationResponse);
System.err.println("Found a ConceptMap that will map " + valueSetURL + " for this StructureDefinition, but the FHIR server returned an unknown $translate response: " + jsonResponse);
continue;
}
System.out.printf("Found ConceptMap %s which translates (valueCode, system) = (%s, %s) for StructureDefinition %s to (valueCode, system) = (%s, %s) %n", conceptMapId, valueCode, valueSetURL, structureDefinitionURL, translatedCode.getCode(), translatedCode.getSystem());
String translatedStructuredData = valueSetForStructureDefinition.get(translatedCode.getSystem());
if (translatedStructuredData == null) {
System.err.printf("Cannot find the mapping from ValueSet '%s' to its corresponding StructureData for this translation, make sure the corresponding mappings configuration file has it.%n", translatedCode.getSystem());
continue;
}
((ObjectNode) extension).set(URL_OBJECT, JsonNodeFactory.instance.textNode(translatedStructuredData));
((ObjectNode) extension).set(VALUE_CODE_OBJECT, JsonNodeFactory.instance.textNode(translatedCode.getCode()));
translatedSomething = true;
}
return translatedSomething;
}
Aggregations