use of org.hl7.fhir.definitions.model.TypeRef 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.definitions.model.TypeRef in project kindling by HL7.
the class ProfileGenerator method produceOpParam.
private void produceOpParam(String path, List<OperationDefinitionParameterComponent> opd, OperationParameter p, OperationParameterUse defUse) throws Exception {
OperationDefinitionParameterComponent pp = new OperationDefinitionParameterComponent();
pp.setName(p.getName());
if (path.contains("."))
pp.setUse(defUse);
else if (p.getUse().equals("in"))
pp.setUse(OperationParameterUse.IN);
else if (p.getUse().equals("out"))
pp.setUse(OperationParameterUse.OUT);
else
// but this is validated elsewhere
throw new Exception("Unable to determine parameter use: " + p.getUse() + " at " + path + "." + p.getName());
pp.setDocumentation(preProcessMarkdown(p.getDoc(), "Operation Parameter Doco"));
pp.setMin(p.getMin());
pp.setMax(p.getMax());
if (p.getBs() != null) {
if (p.getBs().hasMax())
throw new Error("Max binding not handled yet");
pp.setBinding(new OperationDefinitionParameterBindingComponent().setStrength(p.getBs().getStrength()).setValueSet(buildValueSetReference(p.getBs())));
if (!Utilities.noString(p.getBinding().getName())) {
pp.getBinding().addExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName", new StringType(p.getBinding().getName()));
}
}
if (!Utilities.noString(p.getProfile())) {
pp.addTargetProfile(p.getProfile());
}
opd.add(pp);
if (p.getFhirType().equals("Tuple")) {
for (OperationParameter part : p.getParts()) {
produceOpParam(path + "." + p.getName(), pp.getPart(), part, pp.getUse());
}
} else {
List<TypeRef> trs = new TypeParser(version.toCode()).parse(p.getFhirType(), false, null, null, false);
if (trs.size() > 1) {
if (p.getSearchType() != null)
pp.setSearchType(SearchParamType.fromCode(p.getSearchType()));
pp.setType(Enumerations.FHIRAllTypes.fromCode("Element"));
for (TypeRef tr : trs) {
pp.addExtension(ToolingExtensions.EXT_ALLOWED_TYPE, new UriType(tr.getName()));
if (tr.getParams().size() > 0)
throw new Error("Multiple types for an operation parameter, where one is a reference, is not supported by the build tools");
}
} else {
TypeRef tr = trs.get(0);
if (definitions.getConstraints().containsKey(tr.getName())) {
ProfiledType pt = definitions.getConstraints().get(tr.getName());
pp.setType(Enumerations.FHIRAllTypes.fromCode(pt.getBaseType().equals("*") ? "Type" : pt.getBaseType()));
pp.addTargetProfile("http://hl7.org/fhir/StructureDefinition/" + pt.getName());
} else {
if (p.getSearchType() != null)
pp.setSearchType(SearchParamType.fromCode(p.getSearchType()));
pp.setType(Enumerations.FHIRAllTypes.fromCode(tr.getName().equals("*") ? "Type" : tr.getName()));
if (tr.getParams().size() == 1 && !tr.getParams().get(0).equals("Any"))
pp.addTargetProfile("http://hl7.org/fhir/StructureDefinition/" + tr.getParams().get(0));
}
}
}
}
use of org.hl7.fhir.definitions.model.TypeRef in project kindling by HL7.
the class DictHTMLGenerator method describeType.
private String describeType(ElementDefn e) throws Exception {
StringBuilder b = new StringBuilder();
boolean first = true;
if (e.typeCode().startsWith("@")) {
b.append("<a href=\"#" + e.typeCode().substring(1) + "\">See " + e.typeCode().substring(1) + "</a>");
} else {
for (TypeRef t : e.getTypes()) {
if (!first)
b.append("|");
String tn = t.getName();
if (tn.equals("Type"))
tn = "Element";
if (tn.equals("*"))
b.append("<a href=\"" + prefix + "datatypes.html#open\">*</a>");
else
b.append("<a href=\"" + prefix + typeLink(tn) + "\">" + tn + "</a>");
if (t.hasParams()) {
b.append("(");
boolean firstp = true;
for (String p : t.getParams()) {
if (!firstp)
b.append(" | ");
firstp = false;
if (definitions.hasLogicalModel(p)) {
b.append("<a href=\"" + prefix + typeLink(p) + "\">" + p + "</a>[");
boolean firstpn = true;
for (String pn : definitions.getLogicalModel(p).getImplementations()) {
if (!firstpn)
b.append(", ");
firstpn = false;
b.append("<a href=\"" + prefix + typeLink(pn) + "\">" + pn + "</a>");
}
b.append("]");
} else {
b.append("<a href=\"" + prefix + typeLink(p) + "\">" + p + "</a>");
}
}
b.append(")");
}
first = false;
}
}
return b.toString();
}
use of org.hl7.fhir.definitions.model.TypeRef in project kindling by HL7.
the class FhirTurtleGenerator method processTypes.
private void processTypes(String baseResourceName, FHIRResource baseResource, ElementDefn td, String predicateBase, boolean innerIsBackbone) throws Exception {
for (ElementDefn ed : td.getElements()) {
String predicateName = predicateBase + "." + (ed.getName().endsWith("[x]") ? ed.getName().substring(0, ed.getName().length() - 3) : ed.getName());
FHIRResource predicateResource;
if (ed.getName().endsWith("[x]")) {
predicateResource = fact.fhir_objectProperty(predicateName);
// Choice entry
if (ed.typeCode().equals("*")) {
// Wild card -- any element works (probably should be more restrictive but...)
Resource targetResource = RDFNamespace.FHIR.resourceRef("Element");
baseResource.restriction(fact.fhir_cardinality_restriction(predicateResource.resource, targetResource, ed.getMinCardinality(), ed.getMaxCardinality()));
predicateResource.domain(baseResource);
predicateResource.range(targetResource);
} else {
// Create a restriction on the union of possible types
List<Resource> typeOpts = new ArrayList<Resource>();
for (TypeRef tr : ed.getTypes()) {
// TODO: Figure out how to get the type reference code
String trName = tr.getName();
if (trName.equals("SimpleQuantity"))
trName = "Quantity";
String qualifiedPredicateName = predicateName + Utilities.capitalize(trName);
Resource targetRes = fact.fhir_class(tr.getName()).resource;
FHIRResource qualifiedPredicate = fact.fhir_objectProperty(qualifiedPredicateName, predicateResource.resource).domain(baseResource).range(targetRes);
typeOpts.add(fact.fhir_cardinality_restriction(qualifiedPredicate.resource, targetRes, ed.getMinCardinality(), ed.getMaxCardinality()));
}
baseResource.restriction(fact.fhir_union(typeOpts));
}
} else {
FHIRResource baseDef;
if (ed.getTypes().isEmpty()) {
predicateResource = fact.fhir_objectProperty(predicateName);
String targetClassName = mapComponentName(baseResourceName, ed.getDeclaredTypeName());
baseDef = fact.fhir_class(targetClassName, innerIsBackbone ? "BackboneElement" : "Element").addDefinition(ed.getDefinition());
processTypes(targetClassName, baseDef, ed, predicateName, innerIsBackbone);
} else {
TypeRef targetType = ed.getTypes().get(0);
String targetName = targetType.getName();
if (targetName.startsWith("@")) {
// Link to earlier definition
ElementDefn targetRef = getElementForPath(targetName.substring(1));
String targetRefName = targetRef.getName();
String targetClassName = baseResourceName + Character.toUpperCase(targetRefName.charAt(0)) + targetRefName.substring(1);
baseDef = fact.fhir_class(targetClassName, innerIsBackbone ? "BackboneElement" : "Element").addDefinition(ed.getDefinition()).addTitle(ed.getShortDefn());
if (!processing.contains(targetRefName)) {
processing.add(targetRefName);
processTypes(targetClassName, baseDef, targetRef, predicateName, innerIsBackbone);
processing.remove(targetRefName);
}
} else {
// A placeholder entry. The rest of the information will be supplied elsewhere
baseDef = fact.fhir_class(targetName);
}
// XHTML the exception, in that the html doesn't derive from Primitive
if (targetName.equals("xhtml"))
predicateResource = fact.fhir_dataProperty(predicateName);
else
predicateResource = fact.fhir_objectProperty(predicateName);
}
predicateResource.addTitle(ed.getShortDefn()).addDefinition(ed.getDefinition()).domain(baseResource);
baseResource.restriction(fact.fhir_cardinality_restriction(predicateResource.resource, baseDef.resource, ed.getMinCardinality(), ed.getMaxCardinality()));
predicateResource.range(baseDef.resource);
if (!Utilities.noString(ed.getW5()))
predicateResource.addObjectProperty(RDFS.subPropertyOf, RDFNamespace.W5.resourceRef(ed.getW5()));
}
}
}
use of org.hl7.fhir.definitions.model.TypeRef in project bunsen by cerner.
the class Stu3StructureDefinitions method elementToFields.
/**
* Returns the fields for the given element. The returned stream can be empty
* (e.g., for elements with max of zero), or have multiple values (for elements
* that generate fields with additional data in siblings.)
*/
private <T> List<StructureField<T>> elementToFields(DefinitionVisitor<T> visitor, StructureDefinition rootDefinition, ElementDefinition element, List<ElementDefinition> definitions, Deque<QualifiedPath> stack) {
String elementName = elementName(element);
if (shouldTerminateRecursive(visitor, rootDefinition, element, stack)) {
return Collections.emptyList();
} else if (element.getMax().equals("0")) {
// Fields with max of zero are omitted.
return Collections.emptyList();
} else if ("Extension".equals(element.getTypeFirstRep().getCode())) {
return extensionElementToFields(visitor, rootDefinition, element, definitions, stack);
} else if (element.getType().size() == 1 && PRIMITIVE_TYPES.contains(element.getTypeFirstRep().getCode())) {
T primitiveConverter = visitor.visitPrimitive(elementName, element.getTypeFirstRep().getCode());
if (!element.getMax().equals("1")) {
return singleField(elementName, visitor.visitMultiValued(elementName, primitiveConverter));
} else {
return singleField(elementName, primitiveConverter);
}
} else if (element.getPath().endsWith("[x]")) {
// Use a linked hash map to preserve the order of the fields
// for iteration.
Map<String, T> choiceTypes = new LinkedHashMap<>();
for (TypeRefComponent typeRef : element.getType()) {
if (PRIMITIVE_TYPES.contains(typeRef.getCode().toLowerCase())) {
T child = visitor.visitPrimitive(elementName, typeRef.getCode().toLowerCase());
choiceTypes.put(typeRef.getCode(), child);
} else {
StructureDefinition structureDefinition = (StructureDefinition) validationSupport.fetchStructureDefinition(context, typeRef.getCode());
T child = transform(visitor, element, structureDefinition, new ArrayDeque<>());
choiceTypes.put(typeRef.getCode(), child);
}
}
StructureField<T> field = new StructureField<>(elementName, elementName, null, false, true, visitor.visitChoice(elementName, choiceTypes));
return Collections.singletonList(field);
} else if (!element.getMax().equals("1")) {
if (getDefinition(element) != null) {
// Handle defined data types.
StructureDefinition definition = getDefinition(element);
if (shouldTerminateRecursive(visitor, definition, stack)) {
return Collections.emptyList();
} else {
T type = transform(visitor, element, definition, stack);
return singleField(elementName, visitor.visitMultiValued(elementName, type));
}
} else {
List<StructureField<T>> childElements = transformChildren(visitor, rootDefinition, definitions, stack, element);
T result = visitor.visitComposite(elementName, element.getPath(), elementName, rootDefinition.getUrl(), childElements);
List<StructureField<T>> composite = singleField(elementName, result);
// Array types should produce only a single element.
if (composite.size() != 1) {
throw new IllegalStateException("Array type in " + element.getPath() + " must map to a single structure.");
}
// Wrap the item in the corresponding multi-valued type.
return singleField(elementName, visitor.visitMultiValued(elementName, composite.get(0).result()));
}
} else if (getDefinition(element) != null) {
// Handle defined data types.
StructureDefinition definition = getDefinition(element);
if (shouldTerminateRecursive(visitor, definition, stack)) {
return Collections.emptyList();
} else {
T type = transform(visitor, element, definition, stack);
return singleField(elementName(element), type);
}
} else {
// Handle composite type
List<StructureField<T>> childElements = transformChildren(visitor, rootDefinition, definitions, stack, element);
T result = visitor.visitComposite(elementName, element.getPath(), elementName, rootDefinition.getUrl(), childElements);
return singleField(elementName, result);
}
}
Aggregations