예제 #1
0
        private void AddMissingComplexDataTypeElements(SDTreeNode node)
        {
            StructureDefinition dataTypeDefinition;
            ElementDefinition   dataTypeRootElement;

            ElementDefinition[] dataTypeChildElements;

            // if is element in multi level complex type, recall context
            if (multiLevelComplexTypeRevisit.ContainsKey(node))
            {
                dataTypeDefinition    = multiLevelComplexTypeRevisit[node].ComplexDataTypeDefinition;
                dataTypeRootElement   = multiLevelComplexTypeRevisit[node].MultiLevelElementDefinition;
                dataTypeChildElements = dataTypeDefinition.differential.element.GetChildren(dataTypeRootElement).ToArray();
            }
            else  // else check whether is root of complex type
            {
                // don't expand profiles with multi choice types
                if (node.GetElementDefinitionType() == null)
                {
                    return;
                }

                if (node.GetElementDefinitionType().Count() != 1)
                {
                    return;
                }

                ElementDefinitionType elementType = node.GetElementDefinitionType().Single();

                if (elementType == null)
                {
                    return;
                }

                if (!(elementType.IsComplexType() || elementType.IsReference()))
                {
                    return;
                }

                // don't expand root Extension elements
                if ((node.Path == "Extension") && (elementType.TypeName == "Element"))
                {
                    return;
                }

                dataTypeDefinition = FhirData.Instance.FindDataTypeStructureDefinition(elementType.TypeName);

                if (dataTypeDefinition == null)
                {
                    throw new Exception("Could not find FHIR data type " + elementType.TypeName);
                }

                dataTypeRootElement   = dataTypeDefinition.differential.element.GetRootElement();
                dataTypeChildElements = dataTypeDefinition.differential.element.GetChildren(dataTypeRootElement).ToArray();
            }

            List <SDTreeNode> newChildren = new List <SDTreeNode>();

            foreach (ElementDefinition dataTypeChildElement in dataTypeChildElements)
            {
                string lastPathElement = dataTypeChildElement.GetLastPathValue();

                SDTreeNode[] existingChildren = node.Children.Where(t => t.LastPathElementWithoutSliceIndex == lastPathElement).ToArray();

                List <SDTreeNode> currentNewChildren = new List <SDTreeNode>();

                // if child or children don't exist, add the child
                if (existingChildren.Length == 0)
                {
                    SDTreeNode newChild = new SDTreeNode(dataTypeChildElement);
                    currentNewChildren.Add(newChild);
                }
                else // child or children already exists
                {
                    foreach (SDTreeNode existingChild in existingChildren)
                    {
                        // if is a "fake" element, it needs replacing
                        if (existingChild.Element.IsFake)
                        {
                            SDTreeNode   newChild       = new SDTreeNode(dataTypeChildElement);
                            SDTreeNode[] childsChildren = existingChild.Children;
                            existingChild.RemoveAllChildren();
                            newChild.AddChildren(childsChildren);
                            currentNewChildren.Add(newChild);
                        }
                        else // keep the existing child
                        {
                            existingChild.Element.BaseElementDefinition = dataTypeChildElement;
                            currentNewChildren.Add(existingChild);
                        }
                    }
                }

                newChildren.AddRange(currentNewChildren);

                // if complex data type's children have children....argh!  (should only be for the Timing data type)
                if (dataTypeDefinition.differential.element.GetChildren(dataTypeChildElement).Count() > 0)
                {
                    MultiLevelComplexTypePointer multiLevelComplexTypePointer = new MultiLevelComplexTypePointer()
                    {
                        ComplexDataTypeDefinition   = dataTypeDefinition,
                        MultiLevelElementDefinition = dataTypeChildElement
                    };

                    foreach (SDTreeNode currentChild in currentNewChildren)
                    {
                        multiLevelComplexTypeRevisit.Add(currentChild, multiLevelComplexTypePointer);
                    }
                }
            }

            foreach (SDTreeNode childNode in node.Children)
            {
                if (newChildren.All(t => t.LastPathElement != childNode.LastPathElement))
                {
                    newChildren.Add(childNode);
                }
            }

            node.RemoveAllChildren();
            node.AddChildren(newChildren.ToArray());
        }
 private object GetNonReferenceTypeName(ElementDefinitionType type)
 {
     return(GetDataTypeLink(type.WhenNotNull(t => t.code.value)));
 }
 public static bool HasExtensionProfile(this ElementDefinitionType type)
 {
     return(type.WhenNotNull(t => t.profile.WhenNotNull(s => s.Any())));
 }
        private XElement GetTypeTableCell(ElementDefinitionType[] types, SDTreeNode associatedTreeNode = null)
        {
            string result = string.Empty;

            if (types == null)
            {
                if (associatedTreeNode != null)
                {
                    ElementDefinition associatedElement = associatedTreeNode.Element;

                    if (associatedElement.nameReference != null)
                    {
                        if (!string.IsNullOrWhiteSpace(associatedElement.nameReference.value))
                        {
                            return(Html.Td("(see element " + associatedElement.nameReference.value + ")"));
                        }
                    }
                }

                return(Html.Td(string.Empty));
            }

            if (types.Length == 0)
            {
                return(Html.Td(string.Empty));
            }
            else if (types.Length == 1)
            {
                ElementDefinitionType type = types.Single();

                if (type.IsReference())
                {
                    return(Html.Td(GetReferenceTypeName(new ElementDefinitionType[] { type })));
                }
                else if (type.IsExtension())
                {
                    uri profileUri = type.profile.WhenNotNull(t => t.FirstOrDefault());

                    if (profileUri != null)
                    {
                        StructureDefinition structureDefinition = _resourceFileSet.GetStructureDefinition(profileUri.value);

                        if (structureDefinition.IsComplexExtension())
                        {
                            return(Html.Td("(complex extension)"));
                        }
                        else
                        {
                            ElementDefinitionType[] elementDefinitionTypes = structureDefinition.GetSimpleExtensionType();
                            return(GetTypeTableCell(elementDefinitionTypes));
                        }
                    }
                    else
                    {
                        return(Html.Td(string.Empty));
                    }
                }
                else
                {
                    return(Html.Td(GetNonReferenceTypeName(type)));
                }
            }
            else
            {
                if (types.All(t => t.IsReference()))
                {
                    return(Html.Td(GetReferenceTypeName(types)));
                }

                return(Html.Td(types.Select(t => GetNonReferenceTypeName(t)).Intersperse(" | ")));
            }
        }
예제 #5
0
        public SDNodeType GetNodeType()
        {
            if (IsSetupSlice)
            {
                return(SDNodeType.SetupSlice);
            }

            ElementDefinitionType[] types = GetElementDefinitionType();

            if (types != null)
            {
                if (types.Length == 0)
                {
                    return(SDNodeType.Unknown);
                }
                else if (types.Length == 1)
                {
                    ElementDefinitionType elementType = types.Single();

                    if (elementType.IsBackboneElement())
                    {
                        return(SDNodeType.Element);
                    }
                    else if (elementType.IsPrimitiveType())
                    {
                        return(SDNodeType.PrimitiveType);
                    }
                    else if (elementType.IsReference())
                    {
                        return(SDNodeType.Reference);
                    }
                    else if (elementType.IsComplexType())
                    {
                        return(SDNodeType.ComplexType);
                    }
                    else if (elementType.IsExtension())
                    {
                        if (ExtensionDefinition != null)
                        {
                            if (ExtensionDefinition.IsComplexExtension())
                            {
                                return(SDNodeType.ComplexExtension);
                            }
                        }

                        return(SDNodeType.SimpleExtension);
                    }
                    else if (elementType.IsResource())
                    {
                        return(SDNodeType.Resource);
                    }

                    return(SDNodeType.Unknown);
                }
                else
                {
                    if (types.Any(t => t.IsReference()))
                    {
                        return(SDNodeType.Reference);
                    }

                    return(SDNodeType.Choice);
                }
            }
            else if ((Element.PathBeforeSliceIndexing ?? string.Empty).EndsWith(".extension"))
            {
                // hacky but apparently only way to determine extensions within extensions

                return(SDNodeType.SimpleExtension);
            }
            else if (Element.nameReference != null)
            {
                return(SDNodeType.ReferenceToAnotherElement);
            }

            return(SDNodeType.Unknown);
        }